Ruby
![]() Rubyのロゴ | |
パラダイム | 関数型プログラミング、命令型プログラミング、オブジェクト指向プログラミング、リフレクション ![]() |
---|---|
登場時期 | 1995年 |
開発者 | まつもとゆきひろ ![]() |
最新リリース | 3.4.5[1] ![]() |
型付け | 強い動的型付け, ダック・タイピング |
主な処理系 | MRI, YARV, JRuby, IronRuby, MacRuby |
影響を受けた言語 | Ada、Dylan、Perl、Python、Smalltalk、C++、CLU、Eiffel、LISP、BASIC、Lua、Emacs ![]() |
影響を与えた言語 | D言語[2]、Groovy、Swift、Crystal、Scala、Elixir |
プラットフォーム | Microsoft Windows、Linux、*BSD、macOS ![]() |
ライセンス | Rubyライセンス、GPL 2.0、2条項BSDライセンス ![]() |
ウェブサイト | www |
拡張子 | rb、rbw ![]() |
Ruby(ルビー)は、まつもとゆきひろ(通称: Matz)により開発された、簡潔な文法が特徴的なオブジェクト指向スクリプト言語[3]。
日本で開発されたプログラミング言語としては初めて国際電気標準会議(IEC)で国際規格に認証された事例となった[4][5]。
概要
[編集]Ruby は1993年2月24日に生まれ、1995年12月にfj上で発表された。名称の Ruby は、プログラミング言語 Perl が6月の誕生石である Pearl(真珠)と同じ発音をし、「Perlに続く」という意味で、6月の次の誕生石(7月)のルビーから名付けられた[6]。
機能として、クラス定義、ガベージコレクション、強力な正規表現処理、マルチスレッド、例外処理、イテレータ、クロージャ、Mixin、利用者定義演算子などがある。Perl を代替可能であることが初期の段階から重視されている。Perlと同様にグルー言語としての使い方が可能で、C言語プログラムやライブラリを呼び出す拡張モジュールを組み込むことができる。
Ruby 処理系は、インタプリタとコンパイラが存在する(詳しくは#実装を参照)。
可読性を重視した構文となっている。Ruby においては整数や文字列なども含めデータ型はすべてがオブジェクトであり、純粋なオブジェクト指向言語といえる。
長らく言語仕様が明文化されず、Matzによる実装が言語仕様に準ずるものとして扱われて来たが、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と表記されることもある。GPLかArtisticに似た独自ライセンスを選択するデュアルライセンス)で配布されていたが、バージョン1.9.3以降は2-clause BSDLとのデュアルライセンスで配布されている[7]。
設計思想
[編集]Matzは「Rubyの言語仕様策定において最も重視しているのはストレスなくプログラミングを楽しむことである (enjoy programming)」と述べている。
Ruby には Perl や Python とは決定的に違う点があり、それこそが Ruby の存在価値なのです。それは「楽しさ」です。私の知る限り、Ruby ほど「楽しさ」について焦点を当てている言語は他にありません。Ruby は純粋に楽しみのために設計され、言語を作る人、使う人、学ぶ人すべてが楽しめることを目的としています。しかし、ただ単に楽しいだけではありません。Ruby は実用性も十分です。実用性がなければ楽しめないではありませんか。 — まつもとゆきひろ、Ruby プログラミング入門 まえがき 監修者よりのページ
ただし、Matzによる明文化された言語仕様は存在しない。Perlのモットー「やり方はいろいろある (There's More Than One Way To Do It; TMTOWTDI)」は「多様性は善 (Diversity is Good)」というスローガンで Ruby に引き継がれてはいるものの最重要なものではないとも述べており、非推奨な手法も可能にするとともに、そのような手法を言語仕様により使いにくくすることによって自粛を促している。
また、Matzは『まつもとゆきひろ コードの世界 スーパー・プログラマになる14の思考法』でもRubyの開発理由を次のように述べている。
「なぜRubyを開発したのか」。そのように問われるときに、もっとも適切な答えは、Linux開発者であるリーナス・トーバルズの言葉と同じではないかと思います。『それがぼくには楽しかったから』 — まつもとゆきひろ コードの世界 スーパー・プログラマになる14の思考法 P.9
また、英語圏の開発者の間ではMINASWAN (Matz is nice and so we are nice. 和訳: Matzがナイスだから我々もナイスであろう) の標語が用いられている。
「Python、PHP、Perlでは静的型を導入しているため、Rubyも型を導入するべきでは」と長年言われているが、Matzは「Rubyに型を取り入れたくない。DRY (Don't repeat yourself)ではないから」「型宣言することはコンピュータに使われているような気になる」と否定的であり、2019年5月現在Rubyに静的型が導入される予定はない[8]。
クラス名はアルファベットの大文字から始めるという制約があり、日本語などの非ASCII文字のみでクラス名を定義する方法がない。この件についてMatzは以下のように語っており、英語を共通言語として使うべきであるという立場を表明している。
2文字目以降は自由なので、もしどうしても日本語が使いたいのであれば、少々不自然にも見えますが、先頭だけ大文字の接頭辞をつけるのはどうでしょうか。しかし、私個人としては、日本語の変数名などを使うことは、そのプログラムを読む人の範囲を日本語が読める人に限定してしまうことになるので、ひどくもったいないのではないかと感じています。そこで、この点を積極的に改善する気にはなれないのです。[9]
実装
[編集]公式な実装
[編集]Rubyの公式な実装には、以下の二種類が存在する。
- MRI(Matz' Ruby Implementation)
- Matzによって開発されはじめた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 はすでに初期化されています
配列の作成と使用法
a1 = [1, "hi", 3.14, 1, 2, [4, 5]] p a1[2] #=> 3.14 p a1[0..2] #=> [1, "hi", 3.14] p a1[0, 2] #=> [1, "hi"] p a1.reverse #=> [[4, 5], 2, 1, 3.14, "hi", 1] p a1.reverse.flatten #=> [4, 5, 2, 1, 3.14, "hi", 1] p a1.reverse.flatten.uniq #=> [4, 5, 2, 1, 3.14, "hi"]
# いずれも以下を出力 # ["A", "B C", "D"] # 文字列を配列に変換 S1 = "A \n B C\nD\n" p S1.split("\n").map{|_v| _v.strip} # ヒアドキュメントを配列に変換 S2 = <<EOD A B C D EOD p S2.split("\n").map{|_v| _v.strip} # %w記法で配列に変換 p %w(A B\ C D) p %w( A B\ C D )
# %w記法で都道府県コードの配列を作成する例 # [1..47] = ["北海道".."沖縄県"](一部抜粋) p A1 = [nil] + %w(北海道 青森県 岩手県 宮城県) #=> [nil, "北海道", "青森県", "岩手県", "宮城県"] print 4, ": ", A1[4], "\n" #=> "4: 宮城県"
ハッシュの作成と使用法
h1 = {} h1["water"] = "wet" h1["fire"] = "hot" h2 = {"water" => "wet", "fire" => "hot"} h31 = {:water => "wet", :fire => "hot"} h32 = {:"water" => "wet", :"fire" => "hot"} h41 = {water: "wet", fire: "hot"} h42 = {"water": "wet", "fire": "hot"} # いずれも以下を出力 # "hot" p h1["fire"] p h2["fire"] p h31[:fire] p h32[:"fire"] p h41[:fire] p h42[:"fire"] # いずれも以下を出力 # water: wet # fire: hot h1.each { |_k, _v| print _k, ": ", _v, "\n" } h2.each { |_k, _v| print _k, ": ", _v, "\n" } h31.each { |_k, _v| print _k, ": ", _v, "\n" } h32.each { |_k, _v| print _k, ": ", _v, "\n" } h41.each { |_k, _v| print _k, ": ", _v, "\n" } h42.each { |_k, _v| print _k, ": ", _v, "\n" }
制御構造
[編集]ほかの言語でもよくみられるような制御構造を用いることができる。
条件分岐
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 )
ブロック
[編集]ブロックは { ... }
または do ... end
によって囲まれたコード列である。
一行で収まるときは { ... }
、複数行にまたがるときは do ... end
が使用される。
# { ... } "Hello, Ruby!".split { |_s1| puts _s1 }
# do ... end "Hello, Ruby!".split do |_s1| puts _s1 end
gsub()
の罠
[編集]S1 = "ABC-ABC" # ok # 期待どおり => "AびC-AびC" p S1.gsub("B", "び") # NG # 期待 => "AびBC-AびBC" # 結果 => "AびC-AびC" p S1.gsub(/(B)/, "び#{$1}") # ok # 期待どおり => "AびBC-AびBC" p S1.gsub(/(B)/){ "び#{$1}" }
繰り返し処理
[編集]配列の各要素への繰り返し処理
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 a1 #=> [1, 2, 5, 13, 21] p a2 #=> [2, 4, 10, 26, 42] a1.each.with_index(0) { |i1, i2| a1[i2] = i1 * 2 } p a1 #=> [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 (1..5).to_a #=> [1, 2, 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=>""}
ファイルの読み書き
[編集]テキストファイルの処理例
a1 = [] a2 = [] # (例1-1) メモリに余裕があるなら、全行読み込んで、配列にした方が扱いやすい。 aText = File.read(__FILE__).split("\n").map{|_s1| _s1.chomp} aText.each do |_s1| a1 << _s1 if _s1.match("全行") end # (例1-2) メモリに余裕がないときは、1行ずつ読み込んで処理。 File.open(__FILE__, "r") do |_fs| _fs.each_line do |_s1| _s1.chomp! a2 << _s1 if _s1.match("1行ずつ") end end s1 = a1.join("\n") + "\n" s2 = a2.join("\n") + "\n" # (例2-1) output.txt に書き込む File.write("output.txt", s1) # (例2-2) output.txt に追記する File.open("output.txt", "a") do |_fs| _fs.write s2 end puts %x(cat output.txt) =begin Windows: puts %x(type output.txt) 後述「外部コマンド等の利用」に %x() の説明あり =end
バイナリファイル処理に使用するメソッド等
File.read(... => File.binread(... File.open(..., "r") => File.open(..., "rb") File.open(..., "w") => File.open(..., "wb") File.open(..., "a") => File.open(..., "ab") その他、マルチバイト文字を扱うときは、エンコーディングが必要になる。
本処理を後から指定
[編集]実際に行いたい処理をブロックで記述する。前項の後処理の省力化もこれの一例といえる。
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_reader
は getter
メソッドのみの定義である。なおメソッド中では最後に評価された式が返り値となり、明示的な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」
以下、外部コマンド等(コマンド、実行ファイル、スクリプト言語)のうち、Unix系コマンドを利用したコード例を記す。
(例1) 実行/成功可否(true, false)を取得
bool = system("...")
falseコマンドを実行
p b1 = system("false") #=> false if ! b1 STDERR.puts "FALSE" #=> "FALSE" end
(例2) 実行/結果を取得
string = %x(...)
echoコマンドを実行
p s1 = %x(echo) #=> "\n" if s1.strip.length == 0 STDERR.puts "EMPTY" #=> "EMPTY" end
実行中のRubyスクリプトのソースコード各行に連番を付与
print %x(cat #{__FILE__} | nl -ba -w1)
(参考) Rubyのみで実装
File.read(__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' $CmdList = ["sleep 2", "ls -la", "sleep 8"] # Windows版Ruby3.4現在、オプション in_processes: 未対応のようなので in_threads: を使用した。 Parallel.each($CmdList, in_threads: 4) do |_cmd| system(_cmd.strip) end
ヒアドキュメントで実装
require 'parallel' $CmdList = <<EOD # 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
適正なアルゴリズムを使用することで処理速度が改善される事例は多い[10]。
# 例えば、以下のコードが、"fib.rb"に保存されているとき、 # $ ruby ./fib.rb 10 # と実行。 def RtnFibIntr(num = 0) if num == 0 return [1, 2] end if (num & 1) == 0 numHalf = (num / 2).to_i iPm = ((numHalf & 1) == 0 ? 1 : -1) f1, l1 = RtnFibIntr(numHalf) l2 = (l1 * l1) - (2 * iPm) f2 = (f1 * l1) - iPm elsif (num % 8) == 7 f1, l1 = RtnFibIntr(num + 1) f2 = (2 * f1) - l1 l2 = (3 * f2) - f1 else f1, l1 = RtnFibIntr(num - 1) f2 = (3 * f1) - l1 l2 = (2 * f2) - f1 end return [f2, l2] end def SubFib(num = 0) if num > 0 print num, "\t", RtnFibIntr(num - 1)[0], "\n" end end def main() if ARGV.length > 0 i1 = ARGV[0].to_i SubFib(i1) end end main()
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 Windows の ActiveX 環境で Ruby インタープリターを呼び出す ActiveScriptRuby(Internet Explorer 限定だがHTMLに埋めこんでクライアント上で動かすスクリプト言語として Rubyを指定できるようになる)
- Ruby から Win32API やCOMコンポーネントを呼び出すためのライブラリー WIN32OLE
- JavaScript や Flash 上で動く Ruby の処理系 HotRuby
- Ruby によるビヘイビア駆動開発のためのフレームワーク RSpec
- Ruby で書かれたビルドツール Rake
- Ruby で書かれたmacOS パッケージ管理システム homebrew
- Ruby からDirectXを使用するための拡張ライブラリ DXRuby
- Ruby プログラミングを視覚的直感的に開発可能とする、Scratch (プログラミング言語)のRuby対応版(Rubyソースを生成するScratchとも言えるもの)とでも言うべきGUI型IDE Smalruby
Rubyで開発されたアプリケーション
[編集][要出典]
- tDiary
- 影舞
- Hiki
- Chef
- Vagrant
- Ruby on Rails
- qwikWeb
- WEBrick
- Mongrel
- Phusion Passenger
- Puppet
- mikutter
- Serverspec
Rubyを組み込んだアプリケーション
[編集]- RPGツクールXP・RPGツクールVX
- 株式会社エンターブレインから発売されているRPG制作ソフトシリーズのうち、RPGツクールXPとRPGツクールVXでは、Ruby をツクール専用にカスタマイズした RGSSを搭載している。同シリーズの従来ソフトではあらかじめ用意された機能しか使えなかったが、RGSSにより戦闘などのシステムを一から構築する事が出来るようになった。
- RPGツクールMVからは開発言語がJavaScriptに変更になった。
エピソード
[編集]ブロック構造構文の選択理由
[編集]Ruby ではブロック構造を end
で終える構文が採用されているが、Matzは他の構文が採用される可能性があったことを述べている。当時、Emacs 上で end
で終える構文をオートインデントさせた例はあまりなく、Ruby 言語用の編集モードにオートインデント機能を持たせられるかどうかが問題になっていたためである[注釈 1]。実際には数日の試行でオートインデント可能であることがわかり、現在の構文になった。C言語のような{ ... }
を使った構文も検討されていたが、結局これは採用されなかった[12]。
ゆかりのある地域
[編集]Rubyは日本の国産言語として知られており、特にRubyとゆかりのある次の地域は "Rubyの聖地" と呼ばれている。
- 静岡県浜松市 - Matzが日本タイムシェア株式会社(現:TIS株式会社)の浜松市にあった研究所に勤務していた1993年にRubyの開発を開始[13]。
- 愛知県名古屋市 - 株式会社トヨタケーラム(現:株式会社トヨタシステムズ)在籍時、1995年にRubyをオープンソースソフトウェアとして公開[13]。
- 島根県松江市 - 1997年から島根県松江市に移り、同市の株式会社ネットワーク応用通信研究所 (NaCl)フェローとしてRubyの普及に尽力[13][14]。
当初は当然、Matzが書いたコードばかりだったが、2010年前後に主要開発者の立場からは外れ、10年ほど経過した2020年9月8日現在では、RubyのCコード509,802行のうち、Matzがコミットしたのは36,437行で1割以下という状況になっていた[15]。Matzは「意外と多いなという印象です」と語った[15]。一方、Matzがプログラマーとして関わっているmrubyについて同様の方法で測定したところ、67,068行中、25,049行で、しかもmrubyでは他に代理コミットしてもらったものもあるので、「それを加えると32,653行で、約半分ってところですかね」とのことであった[15]。
言語間競争とRuby
[編集](1993年頃)Python(0.9?)は満足できるようなものではなかったからRubyが開発された。公式のリファレンスの用語集に「MatzがPythonに満足していれば Ruby は生まれなかったであろう」と言及されている[6]。
- Ruby on RailsがPythonではなくRubyで作られた理由 - 開発者のハンソンがRubyに恋をしたから
デイヴィッド・ハイネマイヤー・ハンソンが(2004年頃)Ruby on Railsを構築するのにPython(2?)を選ばなかった理由として「私の場合は、恋に落ちたのがRubyなのです。私はRubyに恋をしていますし、もう14年間もそうなのです。(中略)『最適なツール』などというものは存在しないのです。あなたの脳をちょうどいい具合に刺激するパズルがあるだけなのです。今日では、ほぼなんでも作ることができます。そして、それを使って、さらに何でも作れてしまうのです。これは素晴らしいことです。表現や言語、そして思考の多様性に乾杯しましょう!」と質問サイトのQuoraで本人が回答している[15]。
- 「Rubyは死んだ」のか? 検索ワード頻度では分からない、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つの見識だと思います。
どのプログラミング言語が最もよく使われているかを判断することは難しい。[注釈 2]
脚注
[編集]注釈
[編集]- ^ Matzは1988年に Emacs に触れて以来、Emacsを使い続けている[11]。
- ^ TIOBE社はオランダにある会社で、同じオランダ出身のグイド・ヴァンロッサムが生みの親であるPythonは上位にランキングしている(2025年6月現在)。
出典
[編集]- ^ "Ruby 3.4.5 Released"; 閲覧日: 2025年7月16日; 出版日: 2025年7月15日.
- ^ Intro - D Programming Language 1.0 - Digital Mars
- ^ Ruby コミュニティ. “Rubyとは”. 2025年7月28日閲覧。
- ^ 『プログラム言語Ruby、国際規格として承認』(プレスリリース)独立行政法人情報処理推進機構、2012年4月2日 。[リンク切れ]
- ^ 山田祥寛 2021, p. ⅱ.
- ^ a b “Ruby用語集(Ruby 3.4 リファレンスマニュアル)”. 2025年6月24日閲覧。
- ^ “Ruby License”. ruby-lang.org. 2020年9月29日閲覧。
- ^ “まつもとゆきひろさん「Ruby3の目指す未来 –The Year of Concurrency–」〜RubyKaigi 2019 1日目 基調講演”. gihyo.jp (2019年5月14日). 2024年1月31日閲覧。
- ^ “Rubyのクラスと定数の先頭をアルファベット大文字に限定しているのはなぜですか?クラス名を日本語にできないのが他の言語ではできるので少し惜しい気がします。”. Quora. 2022年6月11日閲覧。
- ^ “フィボナッチ数を高速に計算する”. 2025年6月28日閲覧。
- ^ 大竹智也「本書に寄せて」『Emacs実践入門 思考を直感的にコード化し、開発を加速する』(初版第1刷)技術評論社、2012年4月5日、iiiからivページ頁。ISBN 978-4-7741-5002-4。
- ^ まつもとゆきひろ 「探訪 Ruby 第6回」『Linux Magazine』56号、株式会社アスキー、2004年。
- ^ a b c “Tech通信”. 2019年3月1日閲覧。
- ^ 野田, 哲夫 (2013). “オープンソースのプログラミング言語Rubyによる地域産業振興”. 情報管理 56 (6): 355–362. doi:10.1241/johokanri.56.355 .
- ^ a b c d “Rubyレベルのプログラミング言語はどのくらいの部分が発明者だけによるコードなのでしょうか?”. Quora (2020年9月8日). 2022年4月19日閲覧。
- ^ ““Rubyは死んだ”のか?まつもとゆきひろ氏が語る「プログラミング言語サバイバル」とRubyの未来 - Part1”. ログミーTech. 2025年3月19日閲覧。
参考文献
[編集]![]() |
- 高橋征義、後藤裕蔵『たのしい Ruby Rubyではじめる気軽なプログラミング』まつもとゆきひろ監修、ソフトバンクパブリッシング、2002年4月。ISBN 4-7973-1408-7。 - プログラム未経験者向けの入門書。
- 高橋征義、後藤裕蔵『たのしいRuby Rubyではじめる気軽なプログラミング』まつもとゆきひろ監修(第2版)、ソフトバンクパブリッシング、2006年8月。ISBN 4-7973-3661-7。
- 高橋征義、後藤裕蔵『たのしい Ruby』まつもとゆきひろ監修(第3版)、ソフトバンクパブリッシング、2010年3月。ISBN 978-4-7973-5740-0。
- 高橋征義、後藤裕蔵『たのしい Ruby』まつもとゆきひろ監修(第4版)、ソフトバンクパブリッシング、2013年6月。ISBN 978-4-7973-7227-4。
- 高橋征義、後藤裕蔵『たのしい Ruby』まつもとゆきひろ監修(第5版)、ソフトバンクパブリッシング、2016年2月。ISBN 978-4-7973-8629-5。
- 高橋征義、後藤裕蔵『たのしい Ruby』まつもとゆきひろ監修(第6版)、ソフトバンクパブリッシング、2019年3月。ISBN 978-4-7973-9984-4。
- デビット・トーマス、アンドリュー・ハント『プログラミングRuby 達人プログラマーガイド』田和勝訳、まつもとゆきひろ監修、ピアソン・エデュケーション、2001年9月。ISBN 4-89471-453-1。
- Dave Thomas、Chad Fowler・Andy Hunt『プログラミング Ruby 言語編』田和勝訳、まつもとゆきひろ監修(第2版)、オーム社、2006年8月。ISBN 4-274-06642-8。
- Dave Thomas、Chad Fowler・Andy Hunt『プログラミング Ruby ライブラリ編』田和勝訳、まつもとゆきひろ監修(第2版)、オーム社、2006年8月。ISBN 4-274-06643-6。
- Dave Thomas、Chad Fowler・Andy Hunt『プログラミング Ruby 1.9 言語編』田和勝訳、まつもとゆきひろ監修、オーム社、2010年5月。ISBN 978-4-274-06809-6。
- Dave Thomas、Chad Fowler・Andy Hunt『プログラミング Ruby 1.9 ライブラリ編』田和勝訳、まつもとゆきひろ監修、オーム社、2010年5月。ISBN 978-4-274-06810-2。
- David Flanagan、まつもとゆきひろ『プログラミング言語 Ruby』卜部昌平監訳、長尾高弘訳、オライリー・ジャパン、2009年1月。ISBN 978-4-87311-394-4。
- まつもとゆきひろ、石塚圭樹『オブジェクト指向スクリプト言語 Ruby』アスキー〈ASCII software science : Language 11〉、1999年11月。ISBN 4-7561-3254-5。
- まつもとゆきひろ『まつもとゆきひろ コードの世界~スーパー・プログラマになる14の思考法』日経Linux編集、日経BP社、2009年5月。ISBN 978-4-8222-3431-7。
- 山田祥寛『独習Ruby』(新版)翔泳社〈独習シリーズ〉、2021年9月13日。ISBN 978-4-7981-6884-5。
関連項目
[編集]外部リンク
[編集]- オブジェクト指向スクリプト言語 Ruby:Ruby公式ウェブサイト
- Rubyアソシエーション
- JISC - JISX3017 プログラム言語Ruby