Rubyとは?

Ruby(ルビー)は、まつもとゆきひろ(通称Matz)により開発されたオブジェクト指向スクリプト言語であり、 従来Perlなどのスクリプト言語が用いられてきた領域でのオブジェクト指向プログラミングを実現する。Rubyは 当初1993年2月24日に生まれ、1995年12月にfj上で発表された。名称のRubyは、プログラミング言語Perlが6月の 誕生石であるPearl(真珠)とほぼ同じ発音をすることから、まつもとの同僚の誕生石(7月)のルビーを取って 名付けられた。

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

Ruby処理系は、主にインタプリタとして実装されている(詳しくは[[実装]]を参照)。

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

フリーソフトウェアとしてruby ライセンス(Ruby License や Ruby’s と表記されることもある。GPLか Artisticに似た独自ライセンスを選択するデュアルライセンス)で配布されている。


Ruby哲学

開発者のまつもとゆきひろは、「Rubyの言語仕様策定において最も重視しているのはストレスなくプログラミン グを楽しむことである (Enjoy programming)」と述べている。(ただし、明文化された公式な言語仕様は2008年5 月現在存在しない。)Perlのモットー「やり方はいろいろある (TMTOWTDI; There’s More Than One Way To Do It)」は「多様性は善(Diversity is Good)」というスローガンでRubyに引き継がれてはいるものの最重要なもの ではないとも述べており、非推奨な手法も可能にするとともに、そのような手法を言語仕様により使いにくくす ることによって自粛を促している。これは言語仕様が「望ましい」習慣の押し付けを行うということであり、洗 脳言語(Babel-17)と言われる一面でもある。


実装

公式な実装

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

MRI(Matz’ Ruby Implementation) 1.8.x以前の公式実装。まつもとゆきひろによって開発されはじめたC言語による実装であり、最も広く使われている。JRubyに対してCRubyと呼ばれることもある。
YARV 1.9.0で採用された、MRIを拡張した公式な処理系。これはソースコードをJIT方式でバイトコードへコンパイルした後、バイトコードを仮想機械上で実行するインタプリタである。

その他の実装

:JRuby:Javaベースの実装。純粋なJavaで行われているため、プラットフォーム非依存の利用が可能。ほとんどのRubyク ラスが組み込みで提供されている。JIT方式に加え、AOT方式のJavaバイトコードへのコンパイラも用意されてい る(AOT方式でコンパイルしたJavaバイトコードはJRubyが無くても他のJavaプラットフォーム上で動作させるこ とが可能となる)。

  • IronRuby := .NET Framework上でRubyを動作させる実装であり、.NET Frameworkのライブラリと連携させることができる。JIT方式のバイトコードインタプリタ。共通言語基盤に準拠した実装(Monoなど)で動作するため、プラットフォーム非依存の利用も可能(ただし、ソースコードが.NET Frameworkのライブラリに依存している場合はMonoでの動作は不可能)。
  • RubyCocoa、MacRuby := いずれもMac OS X上で動作するRuby実装。Cocoaを含む様々なフレームワークとの連携が可能。RubyCocoaはMac OS X Leopard以降に標準でインストールされており、MacRubyはRubyCocoaの問題点を解決するために開発されている。
  • Rubinius := 仮想機械上でRubyを実行するJIT方式のバイトコードインタプリタ。大部分がRubyで実装されている。

その他 Parrot上でRubyを動作させるための実装なども開発されている。

競合言語としてのPython

プログラミング言語としてのRubyは大雑把に言うと「Perlのオブジェクト指向版」、つまりインタプリタで実行する高機能なスクリプト言語でありオブジェクト指向機能を持つもの、と位置づけることができるが、この位置付けはスクリプト言語Pythonと同じである。このことがそれぞれの言語のユーザ同士の間で「どちらの言語が優れているか」といった論争を生んできた。しかしその論争は技術的な細部にとらわれた不毛な議論になることも多かった。

ここであえて両者の細部を比較はしないが、ユーザ数や書かれたシステムの数量・質などを現時点で比べると世界的にはPythonの方が人気が高い。一方、日本では開発者が日本人であることもあり、Rubyの人気は高く書籍も多く出版されている。とはいえ2004年前後まで圧倒的なキラーアプリがなく、tDiaryやバグトラッキングシステム「影舞」程度しか知られていなかったため、大きな普及には至らなかった。ところが2004年末に発表され2005年に大ブレイクしたRuby on Railsにより一気に注目を集めている。


基本的なコード

# 文字リテラルを含め全てがオブジェクトである
-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'}
puts hash['fire']       # 表示:  hot
 
hash.each_pair 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
 
n = 0
while n < 3
  puts 'foobar'
  n += 1
end
# 表示:         foobar
#               foobar
#               foobar

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

ブロックとイテレータ

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

ブロックの表記方法には二つの方法がある。メソッドの末尾に記述することで機能する

{ puts "Hello, World!" }

do puts "Hello, World!" end

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

繰り返し処理

配列の各要素への繰り返し処理
list = [1, 2, 5, 13, 21]
list.collect!{|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の例と同じ

後処理の省力化

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

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

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

begin
  file = File.open('file.txt', 'w+b')
  file.puts 'Wrote some text.'
ensure
  file.close
end
本処理を後から指定

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

def bfs(list)       #配列をツリーに見立てた処理
  while not 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}

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

H3 クロージャ

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

H5 クロージャとなるようなブロックの引数渡し
H6 クロージャとなるようなブロックの引数渡し
# オブジェクトのインスタンス変数(変数名の頭に@が付く)でブロックを記憶。
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

“クロージャ”:ruby_01_memo-1.html

クラス

次のコードは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
  # 例外処理
ensure
  # 例外の発生に関わらず必ず実行される処理
end

Rubyの周辺技術

  • 分散オブジェクトを実現するdRuby
  • Apache HTTP Serverに組み込むためのmod ruby
  • サーバサイドでHTMLへの埋め込みRuby文を実現するeRuby
  • Rubyスクリプトに埋め込むことができる文書形式RD
  • RubyによるRDを採用したWikiクローン、RWiki
  • RubyからSDLライブラリを扱えるようにするRuby/SDL
  • RubyからDelphiを扱えるようにするApollo
  • RubyによるWebアプリケーションフレームワークRuby on Rails
  • Rubyの別の処理系であるYARV(Yet another RubyVM)
  • Rubyの統合開発環境RDE(Ruby Development Environment)
  • RubyのコードをWindowsの実行形式ファイルに変換するExerb
  • Ruby用のライブラリ管理システムであるRubyGems
  • Microsoft WindowsのActiveX環境でrubyインタープリターを呼び出すActiveScriptRuby (Internet Explorer限定だがHTMLに埋めこんでクライアント上で動かすスクリプト言語としてRubyを指定できるようになる - サーバ上で動作する eRubyとは区別すること)
  • RubyからWin32APIやCOMコンポーネントを呼び出すためのライブラリー WIN32OLE
  • JavaScriptやFlash上で動くRubyの処理系HotRuby
  • Rubyによるビヘイビア駆動開発のためのフレームワークRSpec
  • Rubyで書かれたビルドツール Rake

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

  1. tDiary
    1. 分散オブジェクトを実現するdRuby
  2. 影舞
  3. Hiki
  4. Ruby on Rails
  5. Redmine
  6. qwikWeb
  7. WEBrick

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

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

エピソード

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

Column 1 Column 2 Column 3
Cell Contents More Stuff And Again
You Can Also Put Pipes In Like this |
Column 1 Column 2 Column 3
Things Don’t Need
To Look Pretty
Fun With Tables
left-aligned column right-aligned column centered column
$100 $100 $100
$10 $10 $10
$1 $1 $1