Ruby

Rubyは、まつもとゆきひろにより開発されたオブジェクト指向スクリプト言語。

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

1. 概要
-----

Ruby は1993年2月24日に生まれ、1995年12月にfj上で発表された。名称の Ruby は、プログラミング言語 Perl が6月の誕生石である Pearlと同じ発音をし、「Perlに続く」という意味で、6月の次の誕生石のルビーから名付けられた。競合言語として Perl の他に Python があり、「Matz が Python に満足していれば Ruby は生まれなかったであろう」と公式のリファレンスの用語集で言及されている。

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

Ruby 処理系は、インタプリタとコンパイラが存在する。

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

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

フリーソフトウェアとしてバージョン1.9.2までは Rubyライセンスで配布されていたが、バージョン1.9.3以降は2-clause BSDLとのデュアルライセンスで配布されている。

2. ゆかりのある地域
-----------

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

静岡県浜松市 - 開発者のまつもとゆきひろが日本タイムシェア株式会社の浜松市にあった研究所に勤務していた1993年にRubyの開発を開始。
愛知県名古屋市 - 株式会社トヨタケーラム在籍時、1995年にRubyをオープンソースソフトウェアとして公開。
島根県松江市 - 1997年から島根県松江市に移り、同市の株式会社ネットワーク応用通信研究所 フェローとしてRubyの普及に尽力。

3. 設計思想
-------

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

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

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

また、英語圏の開発者の間ではMINASWAN  の標語が用いられている。

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

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

4. 実装
-----

4.1. 公式な実装
----------

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

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

4.2. その他の実装
-----------

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

5. 例
----

基本的なコード

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

5.1. コレクション
-----------

配列の作成と使用法 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]<WtXmlEndTag />

ハッシュの作成と使用法 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 hothash.delete_if key, value # Deletes :water => 'wet'<WtXmlEndTag />

5.2. 制御構造
---------

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

if "fablic".length > 3 puts 'ya' else puts 'nop' end

表示: yalist = [1, 2, 5, 13, 21] for item in list puts item end

表示: 1
2
5
13
21n = 0 while n < 3 puts 'foobar' n += 1 end

表示: foobar
foobar
foobar<WtXmlEndTag /> 上記、 if "fablic".length > 3 puts 'ya' else puts 'nop' end は、 puts "fablic".length > 3 ? "ya" : "nop" puts puts のような記述もできる。

一部の制御構造は後述するイテレータで代替することができる。

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

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

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

{ ... }method1 { puts "Hello, World!" }

do ... endmethod2 do puts "Hello, world!" end<WtXmlEndTag />

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

5.3.1. 繰り返し処理
-------------

配列の各要素への繰り返し処理 list = [1, 2, 5, 13, 21] list.map! item # 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 # OK "A1B2C-A1B2C" puts "ABC-ABC".gsub/, "1#{$1}2") # NG "A12C-A12C" puts "ABC-ABC".gsub/){"1#{$1}2"} # OK "A1B2C-A1B2C"

5.3.2. 後処理の省力化
--------------

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

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

これは次の例と同様の処理を行う begin file = File.open file.puts 'Wrote some text.' ensure file.close end

5.3.3. 本処理を後から指定
----------------

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

def bfs #配列をツリーに見立てた処理 until list.empty? unit = list.shift yield unit #ブロックの内容を実行 unit.eachv if defined? unit.push end end bfs {|v| p v}

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

5.3.4. クロージャ
------------

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

オブジェクトのインスタンス変数でブロックを記憶。def remember @block = p end

nameを受け取るブロックを引数に、上記のメソッドを呼び出す。remember {|name| puts "Hello, " + name + "!"}

後に必要になった時点でクロージャを呼び出す。@block.call

表示:"Hello, John!"<WtXmlEndTag />

メソッドからクロージャを返す例 def create_set_and_get return proc x, proc { value } end

setter, getter = create_set_and_get setter.call getter.call # => 21<WtXmlEndTag />

5.4. クラス
--------

次のコードは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 end

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

def to_s "#{@name} " end

attr_reader :name, :age end

group = [ Person.new, Person.new, Person.new ]

puts group.sort.reverse<WtXmlEndTag />

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

5.5. 例外処理
---------

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

例外にはメッセージを追加することもできる raise "This is a message"

さらに例外のタイプも指定できる raise ArgumentError, "Illegal arguments!"

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

通常処理rescue

例外処理。引数を省略すると、StandardErrorのサブクラスの例外のみ処理するrescue SomeError

例外処理。SomeErrorの例外のみ処理する。ensure

例外の発生に関わらず必ず実行される処理else

例外が発生しなかったときに実行される処理end<WtXmlEndTag />

5.6. 不向きな処理
-----------

ベンチマークテストで使用される以下のようなコードを実行したとき、処理速度が著しく低下することがある。 i1 = 1000000 while i1 <= 1010000 i2 = i1 - 1 i3 = 2 while i3 <= i1 if  == 0 break elsif i3 == i2 puts i1.to_s break end i3 += 1 end i1 += 1 end

6. Rubyの周辺技術
------------

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

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

tDiary
影舞
Hiki
Chef
Vagrant
Ruby on Rails
GitHub
Metasploit
Redmine
Basecamp
RadiantCMS
qwikWeb
WEBrick
Phusion Passenger
Puppet
mikutter
Serverspec

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

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

9. エピソード
--------

Ruby ではブロック構造を end で終える構文が採用されているが、開発者のまつもとゆきひろは他の構文が採用される可能性があったことを述べている。当時、Emacs 上で end で終える構文をオートインデントさせた例はあまりなく、Ruby 言語用の編集モードにオートインデント機能を持たせられるかどうかが問題になっていたためであるまつもとゆきひろは1988年に Emacs に触れて以来、Emacsを使い続けている。

9.1. 「Rubyは死んだ」
---------------

「Rubyはよく『死んだ』って言われる言語である」とまつもとは認識しておりTwitterがRuby on RailsからJava仮想マシン用言語のScalaに移行した話などを例に出し「Rubyは死んだ」みたいに言われることが増えたとしているほか、オランダのTIOBEという会社が発表しているプログラミング言語の人気ランキングでRubyが上位に入らないことをもってして「Rubyは死んだ」「Rubyは凋落している」と見られることがあるが、「RubyとかRuby on Railsだと、さまざまなジャンルで実際の適用例があるので、なにか困ったとき同じ問題に直面した人を探せたり、あるいはその問題を解決するRubyGemsを見つけられる。そういう点でいうと、トータルの生産性はかなり高いことがある」「実際に仕事として、あるいは自分のプロダクトを作るときに、どんな言語を選択してどういうふうに開発したらいいのかを考えると、Rubyの持っているビジネス上の価値はそんなに下がっていないと思います。たとえ順位が下がって、表面上Rubyの人気が凋落したように見えても、ある意味『まだまだ大丈夫』が1つの見識だと思います」とまつもとは述べている。

9.2. Ruby on RailsがPythonで作られなかった理由
-----------------------------------

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

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

2020年9月8日現在、RubyのCコード509,802行のうち、まつもとがコミットしたのは36,437行で1割以下になっている。

10. 脚注
------

10.1. 注釈
--------

10.2. 出典
--------

11. 参考文献
--------

和書 - プログラム未経験者向けの入門書。

12. 関連項目
--------

Goby
Perl
Python
スクリプト言語
オブジェクト指向プログラミング

13. 外部リンク
---------

name=オブジェクト指向スクリプト言語 Ruby}}：Ruby公式ウェブサイト
[4]