• 追加された行はこの色です。
  • 削除された行はこの色です。
*Ruby / the genuine-object-oriented scripting language [#t2510f81]

#contents

#br
*言語の特徴 [#u83006d2]


**言語の特徴 [#u83006d2]
Rubyがよく分類される言語としての位置づけは、

-純オブジェクト指向言語
-軽量言語
-UNIX指向言語

などが挙げられます。

三つ目の表現はあまり聞きなれないかもしれませんが、
RubyはUNIXで培われた文化を色濃く受け継いでいます。
UNIXコマンド、C言語ライブラリ関数、Perlライブラリルーチンあたりから
借用されたネーミングは数多く、それに馴染んでいる人ならば
容易に動作を予測できるでしょう。
(が、リファレンスはちゃんと見ましょう :-)


また、この特徴を抜きにしても、Rubyはある面では非常に保守的な
手続き型言語です。


*Rubyの導入 [#e68336e0]
■Windowsの場合
**Rubyの導入 [#e68336e0]
[[プログラミング言語/Ruby/インストール]]

Windowsで動くRuby処理系には、いくつか種類があります。
:Cygwin版|
その名の通りCygwin上で動作させるものです。インストールはCygwinのsetup.exeを頼ってくださ(ry

:mswin版|
ふつーにWindowsで動くものです。Windowsとの相性も最も良いでしょう。

:wince版|
W-ZERO3等winCE機で動くものです。配布元はRubyの公式ページではありません。
エディタやDOS窓は自分で探してください。そこまで面倒見れません。
環境設定も自分でがんばってください。
[[配布元:http://uema2.s8.xrea.com/ruby-mswince/]]

さらに、mswin版については、ActiveScriptRubyという、その名の通りActiveScriptエンジンとのブリッジを備えたバージョンもあります。

Windowsへのインストールは、インストーラにまかせっきりでぉkなものが楽でしょう。

[[ダウンロード場所:http://www.ruby-lang.org/ja/downloads/]]
ここの「各環境用バイナリ」の辺り

ただ、インストーラがパスを通してくれるとは限らないので、
環境変数PATHの設定はきちんと確認しましょう。

Windowsでの環境の整え方は[[ここ:http://jp.rubyist.net/magazine/?0002-FirstProgramming]]に詳しく書かれています。インストールから、初めてのRubyスクリプトの実行までかかれてあるので、参考になるでしょう。

■UNIX系OSの場合

DebとかRPMとか、まぁいろいろあるでしょ。
というか、最近のLinuxディストリビューションだと
始めからインストールされている可能性大。

aptが使えるDebianやUbuntuの場合は、

 # apt-get install ruby

yumが使えるFedoraの場合は、

 # yum install ruby

でOKです。ただし、一部のライブラリが入らない場合があるので、その場合はエラーメッセージなどでググるといいでしょう。

■MacOSの場合

MacOS9以前ではRubyで遊べないようです。残念。~
MacOSX 10.2以降であれば、標準でインストールされています。~
MacOSX 10.1の人は、[[Rubyをダウンロード>http://rubyosx.rubyforge.org/]]しましょう。

最新版が欲しい場合は、パッケージ管理ツールを使ってインストールしましょう。~
有名なところではMac Ports、Fink等があります。

MacOSXでのパッケージ管理ツールのインストール方法については、~
既に色々な人がまとめているので割愛します。

■自分でコンパイル!

作成中。
%%ただ、新しめのsedとbisonが要ります。%%
%%autoconfと%%makeは言うまでもなく要ります。
(もちろんgccも)

というわけでUNIX系では無問題ですが、
WinだとMinGW+MSYSが無難かと思われます。
Cygwinもアリでしょうが、MinGWでコンパイルした拡張ライブラリは
そのままmswin版Rubyでも動いたりするので。

■新たな動向
-IronRuby ... [[IronPython]]のように、Silverlight上のMS製Ruby処理系。
-CodeGear製Ruby IDE


*動作を確認 [#t02614c7]
***動作を確認 [#t02614c7]
Windowsならコマンドプロンプト、UNIXならシェルに
  ruby -v
と訪ねてみましょう。インストールに成功していれば、
バージョン情報を教えてくれるはずです。

*Hello, world! [#jd458477]

***Hello, world! [#jd458477]
定番ですな。

  print "hello, world!"


*Rubyドキュメントでの慣習 [#k695d865]
**文法 [#fbed15f8]
などをさらっと流して書く。

[[プログラミング言語/Ruby/言語ダイジェスト]]


**Rubyドキュメントでの慣習 [#k695d865]
メソッドとかを説明文中に表記するさい、
それなりに決まった流儀があります。
知っておくとマニュアルとかが読みやすい鴨。

- Hoge#piyo
- Foo.bar
- Vipper::IQ

上から順に、

- Hogeクラスのオブジェクトが持つpiyoというメソッド
- Fooクラスが持つメソッド(Javaでいうstaticメソッド)
- Vipperクラスが持つ定数IQ

*文法 [#fbed15f8]
Rubyは行指向型言語です。つまり、改行が一文の区切りとなります。
ドキュメントの形式
- [[プログラミング言語/Ruby/RD]]
- [[プログラミング言語/Ruby/RDoc]]

文末記号としてセミコロン';'も使えるのですが、一行に複数の文を書きたいのでもない限り必要ありませんし、推奨されてもいません。rubyのパーザはとかく巨大で複雑なので、少しでも負担を減らしてあげましょう。

  class NoVipError < StandardError ; end

↑セミコロンで文を区切る頻出例。中身のない例外クラスの定義。

なお、Cと同様に、バックスラッシュを打つことで行を継続させることができますし、メソッド呼び出しの引数も複数行にわたって書くことができます。

どこでなにが複数行にわたっての記述が可能か、ということはおおむねユーザの直感にそぐうように決められているので、問題はないでしょう(CやPerlプログラマなら、この直感はより鋭くなるでしょう)。


*コメント [#k72682c4]
  #行末までコメントだぜ
シェルスクリプトやPerlと同じです。

  =begin
    RDを書くところ。
  =end

このように、「'=begin'」のみの行から「'=end'」のみの行
までの間もコメントとして処理系には無視される。
クラスやメソッドの説明をRD(Ruby Document)形式で
書くために使われたりする。

*変数 [#m9b7f45e]
Rubyの変数には型がなく、宣言は初回の代入と同時に
行われます(例外あり)。

Javaな人は「Objectクラスへの参照」型が唯一の型だ、
と考えてもいいかもしれません。Rubyの値はすべてオブジェクト
であり、Objectクラスをスーパークラスに持ちますから。

Rubyの変数には数種類ありますが、その種類はPerlのファニー文字の
ようにプレフィクスに左右されます。

:ローカル変数  -- local_variable|
普通に英数字・アンダーバーで名前をつけます。
宣言は代入と同時で、一度も代入していない変数名を参照すると叱られます。
なお、その場合、引数なし・カッコ省略メソッド呼び出しと区別が付かないので、rubyはそのように叱ります。

:グローバル変数 -- $global_variable|
危険なアイツ。
「$」を先頭に付けます。一度も代入せずに参照するとnilを返します。そういう意味でも危険です
(「$var」と間違って「$val」とタイプしてもエラーになりません)。
自分で作った変数ならば、「「$」が先頭 = グローバル変数」なのですが、組み込み変数の中には例外があるので注意が必要です。

:定数 -- Constant|
Cの感覚な人は、たとえばArrayオブジェクトが入った定数Arrに向かって
 Arr.push("hoge")
とかで内容を変えられることに困惑するかもしれません。
この場合、定数として変更不可能なのは「参照先」です。「参照先のオブジェクトの内容に関する変更の禁止」は、また別の方法があります。
大文字から名前が始まるとそれは定数とされ、constやfinalのような特別な修飾はありません。宣言(つまり代入)されていない定数を参照するとエラーになります。

:インスタンス変数 -- @instance_variable|
オブジェクトの状態。
「@」から始まり、宣言なしに参照するとnilを返します。
C++やJavaなひとはメンバ変数のことだと思ってください。
ただし可視性は設定できず、例外なくクラスの外からはアクセスできません。セッタ・ゲッタを定義する必要があります。

:クラス変数 -- @@class_variable|
同じクラスのインスタンスに共通の変数。
「@@」から始まり、宣言なしに参照するとエラーになります。
Javaな人はstaticなメンバと似たようなものだと思ってください。

*リテラル [#xae3e799]
Rubyのリテラル表現は豊富です。以下に代表的なものを挙げます。

■数値リテラル(Numeric)

|123     |整数|
|4567.89 |実数|
|?a      |aの文字コード|

■文字列リテラル(String)

|"double_quote" |式展開などが解釈されます|
|'single_quote' |書いたままになります|
|`back_quote`   |コマンドとして実行し、出力を値とします|

■□式展開

  val = 123
  puts "put #{val} value"
上のコードの出力は
  put 123 value
となります。ダブルクォート文字列中に#{ ... }で囲った
Rubyの式を書くと、それの値を文字列で表現して埋め込みます。


■配列リテラル(Array)

[12, "abc", 123.45]~
... コンマで区切って要素を指定します。もちろん一つも要素を指定
しない(`[]'; 空の配列)ことも可能です。

■ハッシュリテラル(Hash)

{ "key" => "value", "KEY" => 123 }~
... コンマで区切ってキーと値のペアを指定します。

■シンボルリテラル(Symbol)

:symbol ... symbolというSymbolオブジェクトを生成します。


*ブロック付きメソッド呼び出し [#t9f4cd37]
メソッドに引数としてオブジェクトを渡すのみならず、処理のカタマリを渡すことができます。

  method_name(arg, ...) do |x|
    ...
  end

  method_name(arg, ...){|x|
    ...
  }

のように記述すると、method_name内に処理を引き渡せます。
いわゆるクロージャ、無名関数あたりのことだと思ってもらえると。

  def method_name(arg, ...)
    ...
    yield(x)
    ...
  end

引き渡した処理は、yield(x)のように、必要ならば引数を与えてメソッド内で呼び出せます。
イテレータなども、この機能によって実装されています。

■[少しわかる人へ]

要はレキシカルクロージャっぽいものを1つだけメソッドに与えてやる
機能が文法として用意されてると思ってもらえれば。


*Rubyの真偽評価 [#jbb0c75c]
以下に述べる条件分岐などで、Rubyの値(=オブシェクト)がどの
ように真偽評価されるかを説明します。

結論から言うと、Rubyにおける偽とはfalseとnilであり、
それ以外のあらゆるオブジェクトは真です。

明示的に真を表す代表的な値にtrueがあります。

これら(true, false, nil)は%%予約語ではなく%%(嘘です。予約語です。が)
それぞれTrueClass, FalseClass, NilClassの唯一のインスタンスです。


*制御構造 [#bd2afe6f]
**条件分岐 [#f3190124]
■if文, if修飾子

  if expr then ...

  ... if expr

  if expr then
    ...
  end

exprを評価して真ならば、ブロック内を実行する。
最後のブロック形式の書き方では、thenは省略可能。

  if expr1 then
    ...  #(a)
  elsif expr2 then
    ...  #(b)
  else
    ...  #(c)
  end

expr1を評価して真ならば(a)部を実行して終わりますが、
そうでない場合、expr2の評価に移ります。

expr2の評価が真ならば(b)を実行し、
それもまた偽ならば(c)を実行します。
elsifはいくつでも使えますし、
もちろんelsifなしでいきなりelseを書いてもOKです。

■unless文, unless修飾子

ifに似た文法をとりますが、unlessは条件式の評価基準が逆です。
つまり、

  ... unless expr

は、exprの評価が偽のときだけ...を実行しますし、

  unless expr then
    ... (d)
  else
    ... (e)
  end

は、exprの評価が真ならば(d)部を実行し、
そうでなければ(e)部を実行します。
ただ、ifにおけるelsifに相当する文はありません。

**繰り返し [#pfda227d]
Rubyにおける繰り返し(ループ)のための文とは、
- while
- until
- for
- イテレータ
です。以下これら総称してただ単にループと呼びます。

■while文

  while cond do
    ...
  end

condの評価が真である限り、ブロック内を実行します。
doは省略可能です。

■until文

  until cond do
    ...
  end

は、if-unlessの関係と同じで、condの評価が偽である限り、
ブロック内を実行します。

■for文

  for x in list
    ...
  end

Rubyのfor文はCなどのものと違い、シェルスクリプトやPerlのforeachに近いです。これは、配列のように複数の要素の集合であるlistに対して、その各要素をxに取り出して順次処理していくときに使われます。

(listの基準 : listのクラスがCollectionだった場合、Collection#eachというメソッドが定義されている必要があります。これはイテレータというやつです。Rubyのforは内部的にこれを利用しています)

■イテレータ

例:Array#each

  array = [1, 2, 3, 4, 5]
  
  array.each do |x|
    p x #=>1, 2, 3, 4, 5
  end

ブロック付きメソッド呼び出しを利用して、
わざわざカウンタ用の変数を用意したり、脱出条件を書かなくても全要素
に対して同じ処理を繰り返せます。

  loop do
    ...
  end

のように、一見制御構造のようなイテレータから、

  n = 1
  
  n.upto(10) do |x|
    p x  #=>1, 2, 3, ..., 9, 10
  end

のように、用途が特化した便利なイテレータもあります。


■break, next, redo, retry

ループ内でのフロー制御文です。
:break|現在のループから脱出します。
:next|現在のループの、現在の回の残りの文を飛ばして、次の繰り返しに移ります。
:redo|現在のループの、現在の回の繰り返しをまた初めからやり直します。
:retry|現在のループを始めからやり直します。

**例外処理 [#q496224f]
  begin
    ...  #(a)
  rescue ExClass => ex
    ...  #(b)
  else
    ...  #(c)
  ensure
    ...  #(d)
  end

begin ... endブロック内(の、(a)部)で起きた例外を、
rescueで捕捉します。

rescueのExClassには捕捉する例外クラスを指定し、
=> ex で、exという変数に捕捉した例外オブジェクトを
代入します。どちらも省略可能で、ExClassを省略した場合は
RuntimeErrorクラスを指定したとみなされます。

指定した例外クラスと、その全てのサブクラスのオブジェクトを
捕捉します。

elseは1つ以上のrescueと組で、例外が発生しなかった場合、
(c)部を実行します。

ensure以下の(d)部は、例外が捕捉されようがされまいが
実行する文を記述します。

もちろん、rescue、else、ensureは省略可能です。
…が、rescueの一つも書かずにbegin ... endでくくっても
しょうがないんですが。

*クラス定義 [#pb39a7b7]
せっかくの純オブジェクト指向言語ですから、クラスの作り方をば。

  class ClassName < SuperClassName
    ...
  end

「< SuperClassName」は名の通り継承するクラスを指定します。省略すると自動的にObjectクラスを継承します。

ClassNameは大文字で始める必要があります。定数と同じです(というか、まんま定数なのですが)。

定義したクラスのインスタンスはobj = ClassName.new()のカタチで作れます。カタチを見て判るとおり、newは予約語ではなくメソッド名で、普通に変数名とかにも使えます。

生成したクラスを初期化したい場合、C++やJavaでいうコンストラクタのようなものを定義します。class ... end内で定義されるinitialize()というメソッドがそれです。newは自分の引数をinitializeに丸投げします。


クラスと似たようなものにモジュールがあります。

  module ModuleName
    ...
  end

モジュールはクラスと違って継承できず、インスタンスも持てません。

しかし、include ModuleNameによってそのモジュールで定義した機能をクラス定義中に取り込むことができます(Mix-In)。

■アクセス制御

  class ClassName
  public
    ... #(A)
  private
    ... #(B)
  protected
    ... #(C)
  end

(A)で定義したメソッドはクラス定義の外から(つまりそのクラスのインスタンスをレシーバにして)呼び出せます。

(B)で定義されたメソッドはクラス定義内からしか呼び出せません。

(C)で定義されたメソッドですが、C++やJavaのprotectedとは意味合いが違い、自分のクラスとそのサブクラスからだけ呼べるメソッドになります。

■attr系メソッド -- アクセサ定義

Rubyオブジェクトのインスタンス変数は外からはアクセスできません。がセッタとゲッタを定義することでその問題を回避します。

その場合、set_member(val)、get_member()のような名前で定義するのはRubyでは一般的ではありません。member=(val)、member()のように定義して、あたかもメンバやらプロパティへの代入や参照のように見せかけることができます。インスタンス変数名とメソッド名が衝突しないからです。

ただ、外からアクセスする必要があるインスタンス変数全てに、いちいち
  def member()
    @member
  end
  
  def member=(val)
    @member = val
  end
などと記述しているのは無駄すぎます。そこで、上記のような定義を行うことを請け負ってくれるメソッドがあります。
- attr_reader ..... 前者(ゲッタ)を定義
- attr_writer ..... 後者(セッタ)を定義
- attr_accessor ... 両方を定義


//// 元ネタのページ自体ないので。
//
//*実際のコードによる説明 [#tf295c31]
//- [[Rubyコードリーディング:しりとりゲーム]]
//
//*初心者用課題:解答例 [#g81628d9]
//[[初心者用課題]]で取り上げられている問題をRubyで扱ってみる。
//- [[Ruby:初心者用課題解答例]]

*テキトーな用語集 [#afc6c832]
**テキトーな用語集 [#afc6c832]
:Matz|
Rubyの生みの親であるまつもとゆきひろ氏のこと。

:モルモン教|
キリスト教の宗派。Matzはこの信者。よく煽りのネタにされたが、あまりにイジられすぎて、最早2chRubyスレの習慣と化しつつある。

:Duck Typing|
アヒルは、アヒルみたいに振舞うからアヒルとして認識されるんだぜ、という考え。つまりvipperがVipperクラスのインスタンスだからVipperなんだなー、と考える
のではなく、
aori()やtsuri()など、Vipperらしい振る舞いをする(メソッドを持つ)からこそ、そのvipperというオブジェクトはVipperなんだなー、と捉える考え。
静的型付け言語における「型」とはその名の通りコンパイル時に決定できる変数の情報であるが、Rubyのような動的型付け言語では「型」=「応答できるメッセージ」と考える、それがDuck Typing。たしかSmalltalk辺りに由来する。

:関数|
Rubyに関数なんてものはない。
…が、例えばトップレベルで定義されたメソッドはレシーバなしで
 n = method()
のように書ける。そのようなメソッドを関数と呼び習わす。


*周辺ツール/ライブラリ [#de42668e]
■統合開発環境
**チュートリアル [#u90758fd]
- [[プログラミング言語/Ruby/Rubyそぞろ歩き]]

:RDE|
Ruby Development Environment。Delphi製。~
これひとつからデバックなども可能。保存していないスクリプトでもF5で一発実行。Rubyスクリプトでテキストを編集したりもできる。~
…が、長い間使っていると落ちる。しかも開発停止中。~
…と思いきや、2007/7/7(七夕!)にVer.1.1.1がリリースされました。
[[窓の杜 - コード補完やデバッグ機能を備えたRudyスクリプトの統合開発環境「RDE」v1.1.1:http://www.forest.impress.co.jp/article/2007/07/23/rde.html]]

:RubyWin|
Ruby1.6系ベース。開発停止中。
**コードリーディング [#xba33bd3]
- [[プログラミング言語/Ruby/コードリーディング]]
- [[プログラミング言語/Ruby/練習問題解答例]]

:RDT|
Ruby開発用のEclipseプラグイン。
**周辺ツール/ライブラリ [#de42668e]
[[プログラミング言語/Ruby/開発ツール・ライブラリ]]

■テスティングフレームワーク

:test/unit|
標準添付のテスト駆動開発(Test-Driven Development/TDD)環境。
:RSpec|
振舞駆動開発(Behavior-Driven Development/BDD)環境。
RubyをDSLとしてスペックを記述する。

■ビルドツール

:Rake|
Ruby DSLによってmakefileを書くmakeみたいなもの。

■GUIライブラリ

:Ruby/tk|
Tcl/Tkラッパー。
:Ruby/Gtk+|
:[[VisualuRuby:http://www.osk.3web.ne.jp/~nyasu/software/vrproject.html]]|
Win32 APIラッパーライブラリ。
:[[Apollo:http://www.moriq.com/apollo/]]|
VCLブリッジを備えたRuby処理系+ラッパーライブラリ
:[[WxRuby:http://wxruby.rubyforge.org/wiki/wiki.pl]]|

■ドキュメントの閲覧/作成

■□コマンドラインリファレンスビューワ

:ri|
:Refe|

■□RD

スクリプト埋め込み型のドキュメント形式。
:RDtool|
RD形式のドキュメントを他のフォーマットに変換する。
(HTML、UNIX manページなど)

■□RDoc

ソース解析による自動ドキュメンテーション。
:rdoc|
RDoc処理系。現在標準添付。

■ゲーム作成フレームワーク

:[[Ruby/SDL:http://www.kmc.gr.jp/~ohai/rubysdl.html]]|
マルチプラットフォーム・マルチメディアライブラリSDLのRubyインタフェース。

:[[Miyako:http://www.twin.ne.jp/~cyross/Miyako/]]|
Ruby/SDLをラップし、基本。拡張のAPIを提供する。
独自のメッセージマクロ言語も備える。

:[[MyGame:http://dgames.jp/ja/projects/mygame/]]|
こちらもRuby/SDLのラッパー。Miyakoとは対照的にコンパクト。

:[[RGSS:http://www.enterbrain.co.jp/digifami/products/rpgxp/shinkinou.html]]|
(株)エンターブレインの「RPGツクールXP」に搭載されたRuby拡張。

■パーサジェネレータ

:[[Racc:http://www.loveruby.net/ja/projects/racc/]]|
Pure Rubyパーサジェネレータ。

■EXEファイル作成

:[[Exerb:http://exerb.sourceforge.jp/]]|
Rubyスクリプトを単体で実行可能なEXEファイルにする。
ファイルサイズが大きくなりがちだが、UPX圧縮に対応した。


*参考書籍・WEBページ [#l944f9dc]
**参考書籍・WEBページ [#l944f9dc]
-[[オブジェクト指向言語Ruby:http://www.ruby-lang.org/ja/]]
-[[Rubyリファレンスマニュアル:http://www.ruby-lang.org/ja/man/?cmd=view;name=Ruby%A5%EA%A5%D5%A5%A1%A5%EC%A5%F3%A5%B9%A5%DE%A5%CB%A5%E5%A5%A2%A5%EB]]
-[[Ruby リファレンスマニュアル刷新計画 Wiki:http://redmine.ruby-lang.org/wiki/rurema]]
-[[RAA - Ruby Application Archive(英語):http://raa.ruby-lang.org/]]
-[[Rubyist Magazine るびま:http://jp.rubyist.net/magazine/]]
-[[逆引きRuby:http://www.namaraii.com/rubytips/]]
-[[プログラミング入門 - Rubyを使って -:http://www1.tf.chiba-u.jp/~shin/tutorial/]]
-[[RubyGems.org:http://rubygems.org/]]