Ruby

プログラミング言語 >>他のプログラミング言語 ■カテゴリ / ■テンプレート Ruby（ルビー）は、まつもとゆきひろ（通称: Matz）により開発されたオブジェクト指向スクリプト言語（スクリプト言語とはプログラミング言語の一分類）。 日本で開発されたプログラミング言語としては初めて国際電気標準会議（IEC）で国際規格に認証された事例となった。 Ruby は1993年2月24日に生まれ、1995年12月にfj上で発表された。名称の Ruby は、プログラミング言語 Perl が6月の誕生石である Pearl（真珠）と同じ発音をし、「Perlに続く」という意味で、6月の次の誕生石（7月）のルビーから名付けられた。競合言語として Perl の他に Python があり、「Matz（まつもと） が Python に満足していれば Ruby は生まれなかったであろう」と公式のリファレンスの用語集で言及されている。 機能として、クラス定義、ガベージコレクション、強力な正規表現処理、マルチスレッド、例外処理、イテレータ、クロージャ、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と表記されることもある。GPLかArtisticに似た独自ライセンスを選択するデュアルライセンス）で配布されていたが、バージョン1.9.3以降は2-clause BSDLとのデュアルライセンスで配布されている。 Rubyは日本の国産言語として知られており、特にRubyとゆかりのある地域はRubyの聖地と呼ばれている。 静岡県浜松市 - 開発者のまつもとゆきひろが日本タイムシェア株式会社（現：TIS株式会社）の浜松市にあった研究所に勤務していた1993年にRubyの開発を開始。 愛知県名古屋市 - 株式会社トヨタケーラム（現：株式会社トヨタシステムズ）在籍時、1995年にRubyをオープンソースソフトウェアとして公開。 島根県松江市 - 1997年から島根県松江市に移り、同市の株式会社ネットワーク応用通信研究所 （NaCl）フェローとしてRubyの普及に尽力。 開発者のまつもとゆきひろは、「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に静的型が導入される予定はない。 クラス名はアルファベットの大文字から始めるという制約があり、日本語などの非ASCII文字のみでクラス名を定義する方法がない。この件についてまつもとは以下のように語っており、英語を共通言語として使うべきであるという立場を表明している。 2文字目以降は自由なので、もしどうしても日本語が使いたいのであれば、少々不自然にも見えますが、先頭だけ大文字の接頭辞をつけるのはどうでしょうか。しかし、私個人としては、日本語の変数名などを使うことは、そのプログラムを読む人の範囲を日本語が読める人に限定してしまうことになるので、ひどくもったいないのではないかと感じています。そこで、この点を積極的に改善する気にはなれないのです。 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 を動作させるための実装なども開発されている。 基本的なコード # 文字列、数値を含め、全てがオブジェクトである -199.abs # 199 "ruby is cool".length # 12 "Rick".index("c") # 2 "Nice Day Isn't It?".split(//).uniq.sort.join # " '?DINaceinsty" 配列の作成と使用法 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 "fablic".length > 3 puts 'ya' else puts 'nop' end # 表示: ya list = [1, 2, 5, 13, 21] for item in list puts item end # 表示: 1 # 2 # 5 # 13 # 21 n = 0 while n < 3 puts 'foobar' n += 1 end # 表示: foobar # foobar # foobar 上記、 if "fablic".length > 3 puts 'ya' else puts 'nop' end は、 puts "fablic".length > 3 ? "ya" : "nop" puts( if "fablic".length > 3 "ya" else "nop" end ) puts( case "fablic".length when .. 3 "nop" else "ya" end ) のような記述もできる。 一部の制御構造は後述するイテレータで代替することができる。 Ruby ではブロック付きメソッド呼び出しを用いるコードが好まれることが多い。これを用いると、ユーザー定義の制御構造やコールバックなど様々な処理を簡潔に記述できるからである。 ブロックとは波括弧 {、} または do、end によって囲まれたコード列のことである。メソッド呼び出しの末尾に記述することが出来る。この2つは基本的に同一だが、結合の優先度が異なる。慣習的に一行で書くときは波括弧が、複数行に渡る場合はdo、endが使用される場合が多い。 # { ... } method1 { puts "Hello, World!" } # do ... end method2 do puts "Hello, world!" end ブロック付きメソッド呼び出しが繰り返し処理を主な役割としていたことから、イテレータと呼ばれていた時期がある。しかし、実際には繰り返し処理にとどまらず、様々な使われ方をしているので、最近はブロック付きメソッド呼び出し全体の総称としてイテレータという名称を用いるのは適切でないと考えられている。 配列の各要素への繰り返し処理 list = [1, 2, 5, 13, 21] list.map! {|item| item * 2} # listの各要素を2倍する処理 以下はブロックを使わずに同じことを行う場合 list = [1, 2, 5, 13, 21] n = 0 while n < list.length list[n] *= 2 n += 1 end 指定した回数の繰り返し処理 3.times { puts 'foobar' } # 制御構造の項のwhileの例と同じ 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_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 分散オブジェクトを実現する 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 tDiary 影舞 Hiki Chef Vagrant Ruby on Rails GitHub Metasploit Redmine Basecamp RadiantCMS qwikWeb WEBrick Mongrel（英語版） Phusion Passenger Puppet mikutter Serverspec RPGツクールXP・RPGツクールVX 株式会社エンターブレインから発売されているRPG制作ソフトシリーズのうち、RPGツクールXPとRPGツクールVXでは、Ruby をツクール専用にカスタマイズした RGSSを搭載している。同シリーズの従来ソフトではあらかじめ用意された機能しか使えなかったが、RGSSにより戦闘などのシステムを一から構築する事が出来るようになった。 RPGツクールMVからは開発言語がJavaScriptに変更になった。 Ruby ではブロック構造を end で終える構文が採用されているが、開発者のまつもとゆきひろは他の構文が採用される可能性があったことを述べている。当時、Emacs 上で end で終える構文をオートインデントさせた例はあまりなく、Ruby 言語用の編集モードにオートインデント機能を持たせられるかどうかが問題になっていたためである。実際には数日の試行でオートインデント可能であることがわかり、現在の構文になった。C言語のような{〜}を使った構文も検討されていたが、結局これは採用されなかった。 「Rubyはよく『死んだ』って言われる言語である」とまつもとは認識しておりTwitterがRuby on RailsからJava仮想マシン用言語のScalaに移行した話などを例に出し「Rubyは死んだ」みたいに言われることが増えたとしているほか、オランダのTIOBEという会社が発表しているプログラミング言語の人気ランキングでRubyが上位に入らないことをもってして「Rubyは死んだ」「Rubyは凋落している」と見られることがあるが、「RubyとかRuby on Railsだと、さまざまなジャンルで実際の適用例があるので、なにか困ったとき同じ問題に直面した人を探せたり、あるいはその問題を解決するRubyGemsを見つけられる。そういう点でいうと、トータルの生産性はかなり高いことがある」「実際に仕事として、あるいは自分のプロダクトを作るときに、どんな言語を選択してどういうふうに開発したらいいのかを考えると、Rubyの持っているビジネス上の価値はそんなに下がっていないと思います。たとえ順位が下がって、表面上Rubyの人気が凋落したように見えても、ある意味『まだまだ大丈夫』が1つの見識だと思います」とまつもとは述べている。 デイヴィッド・ハイネマイヤー・ハンソンがRuby on Railsを構築するのにPythonを選ばなかった理由として「私の場合は、恋に落ちたのがRubyなのです。私はRubyに恋をしていますし、もう14年間もそうなのです。（中略）『最適なツール』などというものは存在しないのです。あなたの脳をちょうどいい具合に刺激するパズルがあるだけなのです。今日では、ほぼなんでも作ることができます。そして、それを使って、さらに何でも作れてしまうのです。これは素晴らしいことです。表現や言語、そして思考の多様性に乾杯しましょう！」と質問サイトのQuoraで本人が回答している。 2020年9月8日現在、RubyのCコード509,802行のうち、まつもとがコミットしたのは36,437行で1割以下になっている。