この項目では、プログラミング言語について説明しています。「ルビー」・「ルビ」の他の使い方については「ルビー (曖昧さ回避) 」をご覧ください。
Ruby (ルビー)は、まつもとゆきひろ (通称: Matz)により開発された、簡潔な文法が特徴的なオブジェクト指向 スクリプト言語 [ 3] 。
日本で開発されたプログラミング言語としては初めて国際電気標準会議(IEC) で国際規格に認証された事例となった[ 4] [ 5] 。
Rubyは、1993年 2月24日 に生まれ、1995年 12月にfj 上で発表された。6月の誕生石 Pearl(真珠 )と同じ発音をするプログラミング言語Perl に続くという意味で、7月の誕生石Ruby(ルビー )から名付けられた[ 6] 。
文字列・数値等すべてのデータをオブジェクトとして扱うオブジェクト指向プログラミング 言語である。
クラス 、ガベージコレクション 、例外処理 、Mixin 、正規表現 等の基本機能に、別途機能をRubyGems で追加することが可能である。
2011年3月22日に、JIS規格「JIS X 3017」が制定され、その後2012年4月1日に、日本発のプログラミング言語では初めて、ISO/IEC規格「ISO/IEC 30170」に承認された。
2025年9月現在、言語仕様は明文化されていない[ 注釈 1] 。
バージョン1.9.3以降、BSDとのデュアルライセンス で頒布されている。
Matz は「Rubyの言語仕様策定において最も重視しているのはストレスなくプログラミング を楽しむことである (enjoy programming )」と述べている。
Ruby には Perl や Python とは決定的に違う点があり、それこそが Ruby の存在価値なのです。それは「楽しさ」です。私の知る限り、Ruby ほど「楽しさ」について焦点を当てている言語は他にありません。Ruby は純粋に楽しみのために設計され、言語を作る人、使う人、学ぶ人すべてが楽しめることを目的としています。しかし、ただ単に楽しいだけではありません。Ruby は実用性も十分です。実用性がなければ楽しめないではありませんか。 — まつもとゆきひろ、Ruby プログラミング入門 まえがき 監修者よりのページ
Matz は『まつもとゆきひろ コードの世界 スーパー・プログラマになる14の思考法』でもRubyの開発理由を次のように述べている。
クラス名はアルファベットの大文字から始めるという制約があり、日本語などの非ASCII文字のみでクラス名を定義する方法がない。この件についてMatz は以下のように語っており、英語を共通言語として使うべきであるという立場を表明している[ 7] 。
2文字目以降は自由なので、もしどうしても日本語が使いたいのであれば、少々不自然にも見えますが、先頭だけ大文字の接頭辞をつけるのはどうでしょうか。しかし、私個人としては、日本語の変数名などを使うことは、そのプログラムを読む人の範囲を日本語が読める人に限定してしまうことになるので、ひどくもったいないのではないかと感じています。そこで、この点を積極的に改善する気にはなれないのです。
静的型について、Matz は「(基本設計思想である動的型付け を維持し)静的型付け を導入しない」意思を改めて示した[ 8] 。
Rubyと同様のスクリプト言語(インタープリタ型言語)であるPython 、PHP 、Perl では静的型を導入しており、Rubyも型を導入するべきでは、と長年言われてきました。しかしまつもと さんは「Rubyに型を取り入れたくない(DRYではないから[ 注釈 2] )」、「型宣言することはコンピュータに使われているような気になる」と述べ、Rubyでは静的型は導入しない方針を示しました。
その代わり、静的解析を導入し、型チェックを行えるようにすることを明らかにしました。(中略)静的解析に期待してほしい、とまつもと さんは述べました。
静的解析は、Ruby 3.0.0 から実装された。
MINASWAN 「Matz がniceだから俺らもniceでいよう」[ 9]
そしてRuby(中略)コミュニティを表現した標語に"MINASWAN"というものがあると紹介しました。これは"Matz is nice so we are nice"の略で、もめごとがあっても「matzがniceだから俺らもniceでいよう」と、なだめることが海外のメーリングリストではよく見られるそうです。(中略)今ではスローガンにまで昇華しています。(中略)日本のRubyコミュニティにこの特質を逆輸入したいと考え、講演の最初に取り上げたと述べました。
MRI (Matz Ruby Interpreter)あるいは、CRuby (C言語 で書かれていることに由来する)と呼ばれる。Matz が開発を始めた実装であり最も広く使われている。(狭義として)#YARV に更新される以前(1.8.x以前)のバージョンを指すこともある。YARV は、1.9で採用された#MRI のevalをバイトコードで実行するタイプに置き換えたもの。(狭義の)MRIはソースコードを構文木にコンパイルした後、構文木を解釈する仮想機械であるevalで実行するインタプリタであるが、YARVはソースコードをバイトコードにコンパイルした後、バイトコードを解釈する仮想機械であるevalで実行するインタプリタである。Java などのバイトコードとは違い、このバイトコードはファイルとしては生成されない(ファイルとして静的に外部化することを考慮した設計では基本的になく、シンボルを多用するなどしている)。なお「YARV」は、もともとは開発中におけるその仮想機械の名前だった。JRuby は、Java によるRuby実装である(プラットフォーム非依存の利用が可能)。ほとんどの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 仮想機械 のRuby実装MagLev 。 mruby は、組み込みシステム 向けの軽量版。家電製品 の他、スマートフォン 、コンピュータゲーム などでの使用を想定している。Parrot で動作させるための実装なども開発されている。ここでは、実用途に即した コード例を中心に記載します。クロスプラットフォーム での使用を考慮していますが、Unix系コマンドを利用できない環境では正常に動作しないことがあります。 なお、ウィキブックス には、より多くの基本的 なコード例が記載されています。
文字列・数値等すべてのデータがオブジェクト
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" ヘッダ 情報の付与
#!/usr/bin/env ruby #coding:utf-8 puts "本コードは、これ以降に書く。" 1行目:シバン行 。使用するインタプリタを記述(Windows 系実装では無視される)。 2行目:使用する文字コードを記述。ここではutf-8 を指定。 小文字 または '_' で始まる識別子は ローカル変数
'$' で始まる識別子は グローバル変数
アルファベット大文字 [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 \n D \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: 宮城県" ハッシュ の作成と使用法
h10 = {} h10 [ "water" ] = "wet" h10 [ "fire" ] = "hot" h20 = { "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 h10 [ "fire" ] p h20 [ "fire" ] p h31 [ :fire ] p h32 [ :"fire" ] p h41 [ :fire ] p h42 [ :"fire" ] # いずれも以下を出力 # water: wet # fire: hot h10 . each { | _k , _v | print _k , ": " , _v , " \n " } h20 . 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 " } ほかの言語でもよくみられるような制御構造を用いることができる。
# [Ctrl]+[C] Signal . trap ( :INT ) do puts exit end # キー入力 print "[Y/n] ? " p s1 = STDIN . gets . strip . upcase print "例1-1: " if s1 == "Y" puts true elsif s1 == "N" puts false else puts nil end print "例1-2: " puts ( if s1 == "Y" true elsif s1 == "N" false else nil end ) print "例2: " puts s1 == "Y" ? true : nil print "例3: " print true if s1 == "Y" puts print "例4: " puts ( case s1 when "Y" true when "N" false else nil end ) ブロックは{ ... } またはdo ... end によって囲まれたコード列である。 一行で収まるときは{ ... }、複数行にまたがるときはdo ... end が使用される。
# { ... } "Hello, Ruby!" . split { | _s1 | puts _s1 } # do ... end "Hello, Ruby!" . split do | _s1 | puts _s1 end 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 } " } a1 = [ 1 , 2 , 5 , 13 , 21 ] a2 = [] for i1 in a1 a2 << i1 * 2 end p a2 #=> [2, 4, 10, 26, 42] 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] 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] 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] 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" ) その他、マルチバイト文字を扱うときは、エンコーディングが必要になる。 http 経由でテキストデータを読み込む例(#例外処理 、#gsub() の罠 も参照のこと)
require 'open-uri' # URL Url = "https://ja.wikipedia.org/w/index.php?title=Ruby&action=history&offset=&limit=5" # 検索文字列 Search = "「Ruby」の変更履歴" begin # 全行をメモリに先読みした後、1行ずつ処理する。 URI . open ( Url ) . read . each_line . with_index ( 1 ) do | _s1 , _i1 | _s1 . strip! # 文字列検索 if _s1 . match ( Search ) print ( # 行番号 " \033 [94mL #{ _i1 } \033 [0m \t " , # 一致した文字列を色付け表示 _s1 . gsub ( Search , " \033 [95m #{ Search } \033 [0m" ), " \n " ) end end rescue => e p e end クロージャ となるようなブロックの引数渡し
# オブジェクトのインスタンス変数(変数名の頭に@が付く)でブロックを記憶。 def remember ( & p ) @block = p end # nameを受け取るブロックを引数に、上記のメソッドを呼び出す。 remember { | name | puts "Hello, #{ name } !" } # 後に必要になった時点でクロージャを呼び出す。 @block . call ( "Ruby" ) #=> "Hello, Ruby!" メソッドからクロージャを返す例
def create_set_and_get ( value = 0 ) return proc { | x | value = x }, proc { value } end setter , getter = create_set_and_get p setter . call ( 21 ) #=> 21 p getter . call #=> 21 正規表現 による検索例
# 検索対象文字列 p S1 = "12345 ABCdef あいうえおかきくけこ" # 検索文字列(正規表現) p Rgx1 = /(\d{3}).*?([A-z]+).*?(あ.+お)/ # 検索実行 if S1 =~ Rgx1 # $& で結果取得 print "全体: " , $& , " \n " #=> "12345 ABCdef あいうえお" # $~[1..] で部分一致の配列取得 print "部分: " , $~ [ 1 ..] , " \n " #=> ["123", "ABCdef", "あいうえお"] end 次のコードは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) 想定外のエラーが発生したとき、エラーを分別して実行を継続します。
begin # 処理 rescue error_type => e # error_type の例外あり p e rescue => e # 例外あり p e else # 例外なしのとき実行 ensure # 必ず実行 end 例外なし
# 下記を出力 # Hello Ruby! # else # ensure begin puts "Hello Ruby!" rescue => e puts "rescue" , e else puts "else" ensure puts "ensure" end 例外はraise ... でも発火できる。
例外ありraise "エラー"
# 下記を出力 # rescue # エラー # ensure begin raise "エラー" rescue => e puts "rescue" , e else puts "else" ensure puts "ensure" end 例外ありraise ArgumentError, "Argument エラー"
# 下記を出力 # ArgumentError rescue # Argument エラー # ensure begin raise ArgumentError , "Argument エラー" rescue ArgumentError => e puts "ArgumentError rescue" , e rescue => e puts "rescue" , e else puts "else" ensure puts "ensure" 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 (参考) Rubyスクリプトを動的に評価/実行するときはeval で実装
require 'parallel' def SubEval ( _sec = 0 ) sleep _sec # _sec 秒停止 puts _sec # _sec を表示 end # 便宜上、ヒアドキュメントで記述します。 # 実用途では、標準入力/外部ファイルから読み込んだテキストデータを想定しています。 # 以下、意図的にエラーを混入しているので、実行して確認してみてください。 $CmdList = << EOD SubNoExist() SubEval("Ruby") SubEval(0) SubEval(10) SubEval(5) SubEval(1) SubEval(2) EOD # 入力データに100%の信用がないときは、例外処理を実装。 Parallel . each ( $CmdList . split ( " \n " ), in_threads : 4 ) do | _cmd | _cmd . strip! begin eval ( _cmd ) rescue => e puts " #{ _cmd } => #{ e } " end 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 () RPGツクールXP・RPGツクールVX 株式会社エンターブレインから発売されているRPG制作ソフトシリーズのうち、RPGツクールXP とRPGツクールVX では、Ruby をツクール専用にカスタマイズしたRGSS を搭載している。同シリーズの従来ソフトではあらかじめ用意された機能しか使えなかったが、RGSSにより戦闘などのシステムを一から構築する事が出来るようになった。 RPGツクールMV からは開発言語がJavaScriptに変更になった。Ruby ではブロック構造をend で終える構文が採用されているが、Matz は他の構文が採用される可能性があったことを述べている。当時、Emacs 上でend で終える構文をオートインデントさせた例はあまりなく、Ruby 言語用の編集モードにオートインデント機能を持たせられるかどうかが問題になっていたためである[ 注釈 3] 。実際には数日の試行でオートインデント可能であることがわかり、現在の構文になった。C言語 のような{ ... }を使った構文も検討されていたが、結局これは採用されなかった[ 12] 。
Rubyは日本の国産言語として知られており、特にRubyとゆかりのある次の地域は "Rubyの聖地" と呼ばれている。
当初は当然、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] 。
Python に満足していれば Ruby は生まれなかった Ruby on Rails が Python ではなく Ruby で作られた理由 - 開発者のハンソンがRubyに恋をしたから デイヴィッド・ハイネマイヤー・ハンソン が(2004年頃)Ruby on Railsを構築するのにPython (2.x?)を選ばなかった理由として「私の場合は、恋に落ちたのがRubyなのです。私はRubyに恋をしていますし、もう14年間もそうなのです。(中略)『最適なツール』などというものは存在しないのです。あなたの脳をちょうどいい具合に刺激するパズルがあるだけなのです。今日では、ほぼなんでも作ることができます。そして、それを使って、さらに何でも作れてしまうのです。これは素晴らしいことです。表現や言語、そして思考の多様性に乾杯しましょう!」と質問サイトのQuora で本人が回答している[ 15] 。
「Rubyは死んだ」のか? 検索ワード頻度では分からない Ruby の生産性やビジネス上の価値 「Ruby Business Users Conference 2018 Winter」(2018年12月14日)より抜粋[ 18] 。
RubyとかRuby on Railsだと、簡単なWebアプリケーションをすぐ作ったり、あるいは、さまざまなジャンルで実際の適用例があるので、なにか困ったとき同じ問題に直面した人を探せたり、あるいはその問題を解決するRubyGemsを見つけられる。そういう点でいうと、トータルの生産性はかなり高いことがあるんですね。なので、テクノロジーとしては、2010年代にどんどん新しく出てきた言語が持ってるあの機能がないとかこの機能がないとか、そういうカタログスペック上の欠点があるように思えても、トータルの生産性あるいは効率のよさを考えると、Ruby on Railsのビジネス上の価値は、実はそんなに下がっていないと思うんです。先ほどのTIOBE Indexみたいなランキングは、技術者が新しいことを学ぶときに探すところで順位がついているので、ホットなトピックというんですか、新しく出てきて話題になっているものが上に来がちなんですよね。だから、実際に仕事として、あるいは自分のプロダクトを作るときに、どんな言語を選択してどういうふうに開発したらいいのかを考えると、Rubyの持っているビジネス上の価値はそんなに下がっていないと思います。たとえ順位が下がって、表面上Rubyの人気が凋落したように見えても、ある意味「まだまだ大丈夫」が1つの見識だと思います。
どのプログラミング言語が最もよく使われているかを判断することは難しい。 [ 注釈 5]
^ 「ISO/IEC 30170」による厳密な言語仕様はない。2010年6月以降、言語仕様をテストするRubySpecという外部ライブラリの開発が行われていたが、Ruby 2.2.0リリース直後の2014年12月31日、開発が突然終了された。Ruby 2.2.0が「RubySpecのテストをパスしない」等、MRI側によるRubySpec軽視が一因とされている。“【悲報】Ruby開発者が使わないので「RubySpec」開発終了 ”. 2025年9月16日閲覧。 ^ DRYは「D on'tR epeatY ourself/同じことを繰り返さない」の意。Rubyのデータ型(オブジェクト)は、動的に型変換し再利用される(同じことを繰り返す)存在であって、静的に固定型で利用される(同じことを繰り返さない)存在ではない。 ^ Matz は1988年に Emacs に触れて以来、Emacsを使い続けている[ 11] 。^ 原文のママ。リファレンスマニュアル2.1.0ではmatz 、3.4ではMatz (2025年8月現在)。 ^ TIOBE社はオランダにある会社で、同じオランダ出身のグイド・ヴァンロッサム が生みの親であるPythonは上位にランキングしている(2025年6月現在)。 ウィキメディア・コモンズには、
Ruby に関連するカテゴリがあります。
ウィキブックスに
Ruby 関連の解説書・教科書があります。
低水準言語 高水準言語
1950年代 1960年代 1970年代 1980年代 1990年代 2000年代 2010年代 2020年代
架空の言語