トップQs
タイムライン
チャット
視点

Ruby

オブジェクト指向プログラミング言語 ウィキペディアから

Remove ads

Ruby(ルビー)は、まつもとゆきひろ(通称: Matz)により開発された、簡潔な文法が特徴的なオブジェクト指向スクリプト言語[3]

概要 パラダイム, 登場時期 ...

カテゴリ / テンプレート

日本で開発されたプログラミング言語としては初めて国際電気標準会議(IEC)で国際規格に認証された事例となった[4][5]

Remove ads

概要

Ruby は1993年2月24日に生まれ、1995年12月にfj上で発表された。名称の Ruby は、プログラミング言語 Perl が6月の誕生石である Pearl(真珠)と同じ発音をし、「Perlに続く」という意味で、6月の次の誕生石(7月)のルビーから名付けられた[6]

機能として、クラス定義ガベージコレクション、強力な正規表現処理、マルチスレッド例外処理イテレータクロージャMixin利用者定義演算子などがある。Perl を代替可能であることが初期の段階から重視されている。Perlと同様にグルー言語としての使い方が可能で、C言語プログラムやライブラリを呼び出す拡張モジュールを組み込むことができる。

Ruby 処理系は、インタプリタコンパイラが存在する(詳しくは#実装を参照)。

可読性を重視した構文となっている。Ruby においては整数や文字列なども含めデータ型はすべてがオブジェクトであり、純粋なオブジェクト指向言語といえる。

長らく言語仕様が明文化されず、まつもとによる実装が言語仕様に準ずるものとして扱われて来たが、2010年6月現在、JRuby や Rubinius といった互換実装の作者を中心に機械実行可能な形で明文化する RubySpec という試みが行われている。公的規格としては2011年3月22日にJIS規格(JIS X 3017)が制定され、その後2012年4月1日に日本発のプログラム言語では初めてISO/IEC規格(ISO/IEC 30170)として承認された。

自由ソフトウェアとしてバージョン1.9.2までは Rubyライセンス(Ruby License や Ruby'sと表記されることもある。GPLArtisticに似た独自ライセンスを選択するデュアルライセンス)で配布されていたが、バージョン1.9.3以降は2-clause BSDLとのデュアルライセンスで配布されている[7]

Remove ads

設計思想

要約
視点

開発者のまつもとゆきひろは、「Rubyの言語仕様策定において最も重視しているのはストレスなくプログラミングを楽しむことである (enjoy programming)」と述べている。

Ruby には Perl や Python とは決定的に違う点があり、それこそが Ruby の存在価値なのです。それは「楽しさ」です。私の知る限り、Ruby ほど「楽しさ」について焦点を当てている言語は他にありません。Ruby は純粋に楽しみのために設計され、言語を作る人、使う人、学ぶ人すべてが楽しめることを目的としています。しかし、ただ単に楽しいだけではありません。Ruby は実用性も十分です。実用性がなければ楽しめないではありませんか。まつもとゆきひろ、Ruby プログラミング入門 まえがき 監修者よりのページ

ただし、まつもとによる明文化された言語仕様は存在しない。Perlのモットー「やり方はいろいろある (There's More Than One Way To Do It; TMTOWTDI)」は「多様性は善 (Diversity is Good)」というスローガンで Ruby に引き継がれてはいるものの最重要なものではないとも述べており、非推奨な手法も可能にするとともに、そのような手法を言語仕様により使いにくくすることによって自粛を促している。

また、まつもとは『まつもとゆきひろ コードの世界 スーパー・プログラマになる14の思考法』でもRubyの開発理由を次のように述べている。

「なぜRubyを開発したのか」。そのように問われるときに、もっとも適切な答えは、Linux開発者であるリーナス・トーバルズの言葉と同じではないかと思います。『それがぼくには楽しかったからまつもとゆきひろ、まつもとゆきひろ コードの世界 スーパー・プログラマになる14の思考法 P.9

また、英語圏の開発者の間ではMINASWAN (Matz is nice and so we are nice. 和訳: まつもとがナイスだから我々もナイスであろう) の標語が用いられている。

「Python、PHP、Perlでは静的型を導入しているため、Rubyも型を導入するべきでは」と長年言われているが、まつもとは「Rubyに型を取り入れたくない。DRY (Don't repeat yourself)ではないから⁠」⁠「⁠型宣言することはコンピュータに使われているような気になる」と否定的であり、2019年5月現在Rubyに静的型が導入される予定はない[8]

クラス名はアルファベットの大文字から始めるという制約があり、日本語などの非ASCII文字のみでクラス名を定義する方法がない。この件についてまつもとは以下のように語っており、英語を共通言語として使うべきであるという立場を表明している。

2文字目以降は自由なので、もしどうしても日本語が使いたいのであれば、少々不自然にも見えますが、先頭だけ大文字の接頭辞をつけるのはどうでしょうか。しかし、私個人としては、日本語の変数名などを使うことは、そのプログラムを読む人の範囲を日本語が読める人に限定してしまうことになるので、ひどくもったいないのではないかと感じています。そこで、この点を積極的に改善する気にはなれないのです。[9]
Remove ads

実装

要約
視点

公式な実装

Rubyの公式な実装には、以下の二種類が存在する。

MRI(Matz' Ruby Implementation)
まつもとゆきひろによって開発されはじめたC言語による実装であり、最も広く使われている。狭義として、evalを中心とした部分が次で述べるYARVに更新される以前(1.8.x以前)のバージョンを指して言うこともある。JRuby などに対して CRuby と呼ばれることもある。また、JRuby などに対して、広義として YARV 以降も含んで言うこともある。
YARV
1.9で採用された、MRIのevalをバイトコードを実行するタイプに置き換えたもの。(狭義の)MRIはソースコードを構文木にコンパイルした後、構文木を解釈する仮想機械であるevalで実行するインタプリタであるが、YARVはソースコードをバイトコードにコンパイルした後、バイトコードを解釈する仮想機械であるevalで実行するインタプリタである。Javaなどのバイトコードとは違い、このバイトコードはファイルとしては生成されない(ファイルとして静的に外部化することを考慮した設計では基本的になく、シンボルを多用するなどしている)。なお「YARV」は、もともとは開発中におけるその仮想機械の名前だった。

その他の実装

JRuby
Java 言語による実装。純粋な Java で行われているため、プラットフォーム非依存の利用が可能。ほとんどの Ruby クラスが組み込みで提供されている。インタープリタ・実行時コンパイラ事前コンパイラの3種類が用意されている。事前コンパイラでは、Java バイトコードへ変換し、JRuby が無くても他の Java プラットフォーム上で動作させることが可能となる。
IronRuby
.NET Framework 上で Ruby を動作させる実装であり、.NET Framework のライブラリと連携させることができる。JIT方式のバイトコードインタプリタ。共通言語基盤に準拠した実装(Monoなど)で動作するため、プラットフォーム非依存の利用も可能(ただし、ソースコードが .NET Framework のライブラリに依存している場合は Mono での動作は不可能)。
MacRuby英語版
macOS 上で動作する Ruby 実装。Cocoa を含む様々なフレームワークとの連携が可能。RubyCocoa の問題点を解決するために開発されている。
Rubinius英語版
仮想機械上で Ruby を実行するJIT方式のバイトコードインタプリタ。大部分が Ruby で実装されている。
MagLev英語版
smalltalk仮想マシン上で動作する実装 MagLev
mruby
組み込みシステム向けの軽量版。家電製品の他、スマートフォンゲームなどでの使用を想定している。
その他
Parrot 上で Ruby を動作させるための実装なども開発されている。

コード例

要約
視点

基本的なコード

# 文字列、数値を含め、全てがオブジェクトである。
p -199.abs                                       #=> 199
p "ruby is cool".length                          #=> 12
p "Rick".index("c")                              #=> 2
p "Nice Day Isn't It?".split(//).uniq.sort.join  #=> " '?DINaceinsty"

変数と定数

小文字 または '_' で始まる識別子は ローカル変数

var = 123
p var = 456 #=> 456

'$' で始まる識別子は グローバル変数

$var = 123
p $var = 456 #=> 456

アルファベット大文字 [A-Z] で始まる識別子は 定数

Var = 123
p Var = 456 #=> 警告: 定数 Var はすでに初期化されています

コレクション

配列の作成と使用法

a = [1, 'hi', 3.14, 1, 2, [4, 5]]

a[2]                      # 3.14
a.reverse                 # [[4, 5], 2, 1, 3.14, 'hi', 1]
a.flatten.uniq            # [1, 'hi', 3.14, 2, 4, 5]

ハッシュの作成と使用法

hash = {'water' => 'wet', 'fire' => 'hot'}
hash = {water: 'wet', fire: 'hot'} # シンボルリテラルをキーとする場合、Ruby 1.9 からはこのような Javascript 風の表記ができる。
puts hash[:fire]       # 表示:  hot

hash.each do |key, value|
  puts "#{key} is #{value}"
end

# 表示:               water is wet
#                     fire is hot

hash.delete_if {|key, value| key == :water}   # Deletes :water => 'wet'

制御構造

ほかの言語でもよくみられるような制御構造を用いることができる。

条件分岐

if case

# 以下、いずれも "ya" を出力。
S1 = "fablic" #=> length = 6

if S1.length > 3
  puts "ya"
else
  puts "nop"
end

puts(
  if S1.length > 3
    "ya"
  else
    "nop"
  end
)

puts S1.length > 3 ? "ya" : "nop"

puts "ya" if S1.length > 3

puts(
  case S1.length
  when .. 3
    "nop"
  else
    "ya"
  end
)

繰り返し

繰り返し処理を参照

例外処理

例外処理を参照

ブロック付きメソッド呼び出し

Ruby ではブロック付きメソッド呼び出しを用いるコードが好まれることが多い。これを用いると、ユーザー定義の制御構造コールバックなど様々な処理を簡潔に記述できるからである。

ブロックとは波括弧 {} または doend によって囲まれたコード列のことである。メソッド呼び出しの末尾に記述することが出来る。この2つは基本的に同一だが、結合の優先度が異なる。慣習的に一行で書くときは波括弧が、複数行に渡る場合はdoendが使用される場合が多い。

# { ... }
method1 { puts "Hello, World!" }
# do ... end
method2 do
  puts "Hello, world!"
end

ブロック付きメソッド呼び出しが繰り返し処理を主な役割としていたことから、イテレータと呼ばれていた時期がある。しかし、実際には繰り返し処理にとどまらず、様々な使われ方をしているので、最近はブロック付きメソッド呼び出し全体の総称としてイテレータという名称を用いるのは適切でないと考えられている[10]

繰り返し処理

配列の各要素への繰り返し処理

for

a1 = [1, 2, 5, 13, 21]
a2 = []
for i1 in a1
  a2 << i1 * 2
end
p a2 #=> [2, 4, 10, 26, 42]

while

a1 = [1, 2, 5, 13, 21]
i1 = 0
while i1 < a1.length
  a1[i1] *= 2
  i1 += 1
end
p a1 #=> [2, 4, 10, 26, 42]

each メソッド

a1 = [1, 2, 5, 13, 21]
a2 = []
a1.each { |i1| a2 << i1 * 2 }
p a2 #=> [2, 4, 10, 26, 42]

map map! メソッド

a1 = [1, 2, 5, 13, 21]

# map
a2 = a1.map { |i1| i1 * 2 }
p a1 #=> [1, 2, 5, 13, 21]
p a2 #=> [2, 4, 10, 26, 42]

# map!
a1.map! { |i1| i1 * 2 }
p a1 #=> [2, 4, 10, 26, 42]

times メソッド

a1 = [1, 2, 5, 13, 21]
a1.length.times { |i1| a1[i1] *= 2 }
p a1 #=> [2, 4, 10, 26, 42]

指定した回数の繰り返し処理

# 以下、いずれも "foofoofoo" を出力。
s1 = "foo"

3.times { print s1 }
puts

print (s1 * 3), "\n"

連続する数字の繰り返し処理

# 連続する数字の配列を作成
p ai1 = (1..5).to_a #=> [1, 2, 3, 4, 5]
p ai1[2..4] #=> [3, 4, 5]
p ai1[2, 3] #=> [3, 4, 5]

# 断続する数字をキーにした空のハッシュを作成
hi1 = {}
[0..5, 10, 20..21, 30].each do |e1|
  if e1.class == Range
    e1.each do |i1|
      hi1[i1] = ""
    end
  else
    hi1[e1] = ""
  end
end
p hi1     #=> {0=>"", 1=>"", 2=>"", 3=>"", 4=>"", 5=>"", 10=>"", 20=>"", 21=>"", 30=>""}
p hi1[0]  #=> ""
p hi1[99] #=> nil

# 上記コードをワンオフ向けに特化した例
hi1 = {}
[(0..5).to_a, 10, (20..21).to_a, 30].flatten.each do |i1|
  hi1[i1] = ""
end
p hi1 #=> {0=>"", 1=>"", 2=>"", 3=>"", 4=>"", 5=>"", 10=>"", 20=>"", 21=>"", 30=>""}

gsub()による文字列置換の繰り返し処理

puts "ABC-ABC".gsub("B", "1B2")         # OK "A1B2C-A1B2C"
puts "ABC-ABC".gsub(/(B)/, "1#{$1}2")   # NG "A12C-A12C"
puts "ABC-ABC".gsub(/(B)/){ "1#{$1}2" } # OK "A1B2C-A1B2C"

後処理の省力化

ブロックの内容を実行してから、決められた後処理を行うメソッドもある。

File.open('file.txt', 'w+b') do |file|
  file.puts 'Wrote some text.'
end                             # file.txtはここで自動的に閉じられる

これは次の例と同様の処理を行う(ensure については例外処理の項を参照)

begin
  file = File.open('file.txt', 'w+b')
  file.puts 'Wrote some text.'
ensure
  file.close
end

本処理を後から指定

実際に行いたい処理をブロックで記述する。前項の後処理の省力化もこれの一例といえる。

def bfs(list)       #配列をツリーに見立てた処理
  until list.empty?
    unit = list.shift
    yield unit      #ブロックの内容を実行
    unit.each{|v| list.push v} if defined? unit.push
  end
end
bfs([0,1,[2,3],4,[5,[6,7,8]],9]) {|v| p v}

この例は、ツリーから要素と分枝をつぎつぎと取り出して取り出したものになんらかの処理を行うものである。メソッドの利用者は、なんらかの処理のみを記述すればよく、取り出しのアルゴリズムなど、本質的でない内容に意識を向ける必要がなくなる。

クロージャ

クロージャとなるようなブロックの引数渡し

# オブジェクトのインスタンス変数(変数名の頭に@が付く)でブロックを記憶。
def remember(&p)
  @block = p
end
# nameを受け取るブロックを引数に、上記のメソッドを呼び出す。
remember {|name| puts "Hello, " + name + "!"}

# 後に必要になった時点でクロージャを呼び出す。
@block.call("John")
# 表示:"Hello, John!"

メソッドからクロージャを返す例

def create_set_and_get(value = 0)
  return proc {|x| value = x}, proc { value }
end

setter, getter = create_set_and_get
setter.call(21)
getter.call # => 21

クラス

次のコードはPersonという名前のクラスである。その中、まずinitializeはオブジェクトを初期化するコンストラクタである。ほかに2つのメソッドがあり、1つは比較演算子である<=>オーバーライドしておりArray#sortによりプロパティageでソートすることができる。もう1つのオーバーライド箇所のto_sメソッドは Kernel#puts での表示の形式を整える。attr_readerは Ruby におけるメタプログラミングの例であり、attr はインスタンス変数の入出力を司る、いわゆる値を取得する getter メソッドや値を設定する setter メソッド(アクセサ)を定義する。attr_readergetter メソッドのみの定義である。なおメソッド中では最後に評価された式が返り値となり、明示的なreturnは省略できる。

class Person
  def initialize(name, age)
    @name, @age = name, age
  end

  def <=>(person)
    @age <=> person.age
  end

  def to_s
    "#{@name} (#{@age})"
  end

  attr_reader :name, :age
end

group = [ Person.new("John", 20),
          Person.new("Markus", 63),
          Person.new("Ash", 16)
        ]

puts group.sort.reverse

結果は3つの名前が年の大きい順に表示される

Markus (63)
John (20)
Ash (16)

例外処理

例外は不具合が起こったときraiseの呼び出しで発生させることができる。Ruby での例外は Exception クラスか、そのサブクラスのインスタンスである。

例外にはメッセージを追加することもできる

 raise "This is a message"

さらに例外のタイプも指定できる

 raise ArgumentError, "Illegal arguments!"

例外はrescue節で処理することができ、次のようにコードにrescueを付加するだけである

begin
  # 通常処理
rescue
  # 例外処理。引数を省略すると、StandardErrorのサブクラスの例外のみ処理する
rescue SomeError
  # 例外処理。SomeErrorの例外のみ処理する。
ensure
  # 例外の発生に関わらず必ず実行される処理
else
  # 例外が発生しなかったときに実行される処理
end

不向きな処理

ベンチマークテストで使用される以下のようなコードを実行したとき、処理速度が著しく低下することがある。

i1 = 1000000
while i1 <= 1010000
  i2 = i1 - 1
  i3 = 2
  while i3 <= i1
    if (i1 % i3) == 0
      break
    elsif i3 == i2
      puts i1.to_s
      break
    end
    i3 += 1
  end
  i1 += 1
end

外部コマンド等の利用

Ruby on Railsが有名になったため、Rubyを書いたことがない人は「Rubyは敷居が高い」と敬遠するかもしれない。しかし、それは誤解である。Rubyは「小さなことを少しの努力/Doing small things with little effort」で実装できる言語の一つであり、ちょっとしたプロトタイピング開発や、シェルスクリプトの代替に向いている。

ここでは、既存の外部コマンド等を利用して更なる効果を得る方法を記す(「少ない労力でより多くの成果を/Do more with less」)。

外部コマンド等(コマンド実行ファイルスクリプト言語)を利用するには、以下の方法がある。

(例1) 実行/成功可否を取得

bool = system("...")
戻り値 bool は成功可否 true, false

Unix系の falseコマンド を実行

p b1 = system("false") #=> false
if ! b1
  STDERR.puts "FALSE"  #=> "FALSE"
end

(例2) 実行/結果を取得

string = %x(...)
戻り値 string は実行結果

Unix系の echoコマンド を実行

p s1 = %x(echo)       #=> "\n"
if s1.strip.length == 0
  STDERR.puts "EMPTY" #=> "EMPTY"
end

以下、(例2)とUnix系コマンドを使用したコード例を記す。

実行中のRubyスクリプトのソースコード各行に連番を付与

print %x(cat "#{__FILE__}" | nl -ba -w1)

(参考) Rubyのみで実装

i1 = 0
File.binread(__FILE__).each_line do |_s1|
  i1 += 1
  print i1, "\t", _s1
end
File.binread(__FILE__).each_line.with_index(1) do |_s1, _i1|
  print _i1, "\t", _s1
end

ホームディレクトリの隠しファイルを再帰抽出し、ディレクトリとファイルを配列にする例

a1 = []

# "~/" を絶対パス "/home/foo" に変換
sAbsPath = File.expand_path("~/")

%x(find #{sAbsPath} -type f -name ".*").each_line do |_s1|
  _s1.chomp!
  # ファイル名直前の "/" 位置
  i1 = _s1.rindex("/", -1)
  a1 << [_s1[..(i1 - 1)], _s1[(i1 + 1)..]] #=> (例) ["/home/foo", ".bashrc"]
end

# ディレクトリ順にソート
a1.sort.each { |_a1| print(_a1, "\n") }

(参考) Rubyのみで実装

# 直感的な理解を期待し、敢えて File.basename(), File.dirname() を使用。
a1 = []

# "~/" を絶対パス "/home/foo" に変換
sAbsPath = File.expand_path("~/")

Dir.glob("**/*", File::FNM_DOTMATCH, base: sAbsPath).each do |_fn|
  sPath = File.join(sAbsPath, _fn)
  # ファイルか?
  if FileTest.file?(sPath)
    sFn = File.basename(sPath)
    # "." で始まるファイル名か?
    if sFn[0] == "."
      a1 << [File.dirname(sPath), sFn] #=> (例) ["/home/foo", ".bashrc"]
    end
  end
end

# ディレクトリ順にソート
a1.sort.each { |_a1| print(_a1, "\n") }

Parallel gem で並列処理する例

複数の処理を同時に実行するため、出力結果は、処理が完了する順序によって異なることに注意してください。

require 'parallel'

# Unix系コマンド
$CmdList = ["sleep 2", "find . -type f", "sleep 8", "ls -la"]
$CmdOutput = []

# Windows版Ruby3.4現在、オプション in_processes: は未対応のようなので、in_threads: を例にした。
Parallel.each($CmdList, in_threads: 4) do |_cmd|
  $CmdOutput << %x(#{_cmd})
  # 直接実行/出力するときは system() を使用
  # system(_cmd)
end

puts $CmdOutput.join("\n")

コマンドリストをヒアドキュメントで実装
コマンドが複数のときは、こちらの方が分かりやすい。

require 'parallel'

# Unix系コマンド
$CmdList = <<EOD
  # echo
  echo "USER=${USER}\\nLANG=${LANG}"
  # Ruby
  ruby -e 'print "Hello, Ruby!\\n"'
  # Perl
  perl -e 'print "Hello, Perl!\\n";'
  # Python
  python3 -c "print('Hello, Python!')"
EOD

Parallel.each($CmdList.split("\n"), in_threads: 4) do |_cmd|
  system(_cmd.strip)
end
Remove ads

Rubyの周辺技術

  • 分散オブジェクトを実現する dRuby
  • Ruby スクリプトに埋め込むことができる文書形式RD
  • Ruby によるRDを採用したウィキRWiki
  • Ruby からSDLライブラリを扱えるようにするRuby/SDL
  • Ruby から Delphi を扱えるようにする Apollo
  • Ruby によるウェブアプリケーションフレームワーク Ruby on Rails
  • Ruby の処理系の一つでRuby1.9以後の処理系として採用されている YARV
  • Ruby の統合開発環境 RDE
  • Ruby のコードを Windows の実行形式ファイルに変換する Exerb
  • Ruby 用のライブラリ管理システムである RubyGems
  • Apache HTTP Server に組み込むための mod ruby
  • サーバサイドでHTMLへの埋め込み Ruby 文を実現する eRuby
  • Ruby のコードをJavaScriptへ変換するコンパイラ Opal
  • Microsoft WindowsActiveX 環境で Ruby インタープリターを呼び出す ActiveScriptRubyInternet Explorer 限定だがHTMLに埋めこんでクライアント上で動かすスクリプト言語として Rubyを指定できるようになる)
  • Ruby から Win32APICOMコンポーネントを呼び出すためのライブラリー WIN32OLE
  • JavaScript や Flash 上で動く Ruby の処理系 HotRuby
  • Ruby によるビヘイビア駆動開発のためのフレームワーク RSpec
  • Ruby で書かれたビルドツール Rake
  • Ruby で書かれたmacOS パッケージ管理システム homebrew
  • Ruby からDirectXを使用するための拡張ライブラリ DXRuby
  • Ruby プログラミングを視覚的直感的に開発可能とする、Scratch (プログラミング言語)のRuby対応版(Rubyソースを生成するScratchとも言えるもの)とでも言うべきGUI型IDE Smalruby
Remove ads

Rubyで開発されたアプリケーション

[要出典]

Rubyを組み込んだアプリケーション

RPGツクールXP・RPGツクールVX
株式会社エンターブレインから発売されているRPG制作ソフトシリーズのうち、RPGツクールXPRPGツクールVXでは、Ruby をツクール専用にカスタマイズした RGSSを搭載している。同シリーズの従来ソフトではあらかじめ用意された機能しか使えなかったが、RGSSにより戦闘などのシステムを一から構築する事が出来るようになった。
RPGツクールMVからは開発言語がJavaScriptに変更になった。

エピソード

ブロック構造構文の選択理由

Ruby ではブロック構造を end で終える構文が採用されているが、開発者のまつもとゆきひろは他の構文が採用される可能性があったことを述べている。当時、Emacs 上で end で終える構文をオートインデントさせた例はあまりなく、Ruby 言語用の編集モードにオートインデント機能を持たせられるかどうかが問題になっていたためである[注釈 1]。実際には数日の試行でオートインデント可能であることがわかり、現在の構文になった。C言語のような{〜}を使った構文も検討されていたが、結局これは採用されなかった[12]

ゆかりのある地域

Rubyは日本の国産言語として知られており、特にRubyとゆかりのある次の地域は "Rubyの聖地" と呼ばれている。

まつもとゆきひろが書いたコードの割合

当初は当然、まつもとゆきひろが書いたコードばかりだったが、2010年前後に主要開発者の立場からは外れ、10年ほど経過した2020年9月8日現在では、RubyのCコード509,802行のうち、まつもとがコミットしたのは36,437行で1割以下という状況になっていた[15]。本人は「意外と多いなという印象です」と語った[15]。一方、まつもとがプログラマーとして関わっているmrubyについて同様の方法で測定したところ、67,068行中、25,049行で、しかもmrubyでは他に代理コミットしてもらったものもあるので、「それを加えると32,653行で、約半分ってところですかね」とのことであった[15]

Remove ads

言語間競争とRuby

要約
視点

Pythonは満足できるようなものではなかったからRubyが開発された。公式のリファレンスの用語集に「Matz(まつもと)がPythonに満足していれば Ruby は生まれなかったであろう」と言及されている[6]

Ruby on RailsがPythonではなくRubyで作られた理由 - 開発者のハンソンがRubyに恋をしたから

デイヴィッド・ハイネマイヤー・ハンソンがRuby on Railsを構築するのにPythonを選ばなかった理由として「私の場合は、恋に落ちたのがRubyなのです。私はRubyにをしていますし、もう14年間もそうなのです。(中略)『最適なツール』などというものは存在しないのです。あなたの脳をちょうどいい具合に刺激するパズルがあるだけなのです。今日では、ほぼなんでも作ることができます。そして、それを使って、さらに何でも作れてしまうのです。これは素晴らしいことです。表現や言語、そして思考の多様性に乾杯しましょう!」と質問サイトのQuoraで本人が回答している[15]

検索ワード頻度では分からない、Rubyの生産性やビジネス上の価値

「Ruby Business Users Conference 2018 Winter」(2018年12月14日)より抜粋[16]

RubyとかRuby on Railsだと、簡単なWebアプリケーションをすぐ作ったり、あるいは、さまざまなジャンルで実際の適用例があるので、なにか困ったとき同じ問題に直面した人を探せたり、あるいはその問題を解決するRubyGemsを見つけられる。そういう点でいうと、トータルの生産性はかなり高いことがあるんですね。 なので、テクノロジーとしては、2010年代にどんどん新しく出てきた言語が持ってるあの機能がないとかこの機能がないとか、そういうカタログスペック上の欠点があるように思えても、トータルの生産性あるいは効率のよさを考えると、Ruby on Railsのビジネス上の価値は、実はそんなに下がっていないと思うんです。 先ほどのTIOBE Indexみたいなランキングは、技術者が新しいことを学ぶときに探すところで順位がついているので、ホットなトピックというんですか、新しく出てきて話題になっているものが上に来がちなんですよね。 だから、実際に仕事として、あるいは自分のプロダクトを作るときに、どんな言語を選択してどういうふうに開発したらいいのかを考えると、Rubyの持っているビジネス上の価値はそんなに下がっていないと思います。たとえ順位が下がって、表面上Rubyの人気が凋落したように見えても、ある意味「まだまだ大丈夫」が1つの見識だと思います。

TIOBE社の人気ランキングとは『インターネットでその言語が検索された頻度』を『人気』と言い換えてランク付けしているものである[17][注釈 2]
これは、現実のプログラミング言語の需要を示すものではない。[16]

単なるフェイク的な検索ワード頻度ランキング情報や、SNSのフィルターバブルで偏った情報に囲まれた若い人がSNS情報をもとに空想することと、現実のシステム開発やシステム保守のビジネスの世界で使われている言語の使用頻度は全然異なる。 そして何より、現実のプログラミング言語の寿命はかなり長い。

なお、TIOBE社はオランダにある会社で、同じオランダ出身のグイド・ヴァンロッサムが生みの親であるPythonは、上位にランク付けされている(2025年06月現在)。

脚注

参考文献

関連項目

外部リンク

Loading related searches...

Wikiwand - on

Seamless Wikipedia browsing. On steroids.

Remove ads