Rubyがよく分類される言語としての位置づけは、
などが挙げられます。
三つ目の表現はあまり聞きなれないかもしれませんが、 RubyはUNIXで培われた文化を色濃く受け継いでいます。 UNIXコマンド、C言語ライブラリ関数、Perlライブラリルーチンあたりから 借用されたネーミングは数多く、それに馴染んでいる人ならば 容易に動作を予測できるでしょう。 (が、リファレンスはちゃんと見ましょう :-)
また、この特徴を抜きにしても、Rubyはある面では非常に保守的な 手続き型言語です。
Windowsならコマンドプロンプト、UNIXならシェルに
ruby -v
と訪ねてみましょう。インストールに成功していれば、 バージョン情報を教えてくれるはずです。
定番ですな。
print "hello, world!"
メソッドとかを説明文中に表記するさい、 それなりに決まった流儀があります。 知っておくとマニュアルとかが読みやすい鴨。
上から順に、
Rubyは行指向型言語です。つまり、改行が一文の区切りとなります。
文末記号としてセミコロン';'も使えるのですが、一行に複数の文を書きたいのでもない限り必要ありませんし、推奨されてもいません。rubyのパーザはとかく巨大で複雑なので、少しでも負担を減らしてあげましょう。
class NoVipError < StandardError ; end
↑セミコロンで文を区切る頻出例。中身のない例外クラスの定義。
なお、Cと同様に、バックスラッシュを打つことで行を継続させることができますし、メソッド呼び出しの引数も複数行にわたって書くことができます。
どこでなにが複数行にわたっての記述が可能か、ということはおおむねユーザの直感にそぐうように決められているので、問題はないでしょう(CやPerlプログラマなら、この直感はより鋭くなるでしょう)。
#行末までコメントだぜ
シェルスクリプトやPerlと同じです。
=begin RDを書くところ。 =end
このように、「'=begin'」のみの行から「'=end'」のみの行 までの間もコメントとして処理系には無視される。 クラスやメソッドの説明をRD(Ruby Document)形式で 書くために使われたりする。
Rubyの変数には型がなく、宣言は初回の代入と同時に 行われます(例外あり)。
Javaな人は「Objectクラスへの参照」型が唯一の型だ、 と考えてもいいかもしれません。Rubyの値はすべてオブジェクト であり、Objectクラスをスーパークラスに持ちますから。
Rubyの変数には数種類ありますが、その種類はPerlのファニー文字の ようにプレフィクスに左右されます。
Arr.push("hoge")とかで内容を変えられることに困惑するかもしれません。 この場合、定数として変更不可能なのは「参照先」です。「参照先のオブジェクトの内容に関する変更の禁止」は、また別の方法があります。 大文字から名前が始まるとそれは定数とされ、constやfinalのような特別な修飾はありません。宣言(つまり代入)されていない定数を参照するとエラーになります。
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オブジェクトを生成します。
メソッドに引数としてオブジェクトを渡すのみならず、処理のカタマリを渡すことができます。
method_name(arg, ...) do |x| ... end
method_name(arg, ...){|x| ... }
のように記述すると、method_name内に処理を引き渡せます。 いわゆるクロージャ、無名関数あたりのことだと思ってもらえると。
def method_name(arg, ...) ... yield(x) ... end
引き渡した処理は、yield(x)のように、必要ならば引数を与えてメソッド内で呼び出せます。 イテレータなども、この機能によって実装されています。
■[少しわかる人へ]
要はレキシカルクロージャっぽいものを1つだけメソッドに与えてやる 機能が文法として用意されてると思ってもらえれば。
以下に述べる条件分岐などで、Rubyの値(=オブシェクト)がどの ように真偽評価されるかを説明します。
結論から言うと、Rubyにおける偽とはfalseとnilであり、 それ以外のあらゆるオブジェクトは真です。
明示的に真を表す代表的な値にtrueがあります。
これら(true, false, nil)は予約語ではなく(嘘です。予約語です。が)
それぞれTrueClass, FalseClass, NilClassの唯一のインスタンスです。
■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に相当する文はありません。
Rubyにおける繰り返し(ループ)のための文とは、
■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
ループ内でのフロー制御文です。
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でくくっても しょうがないんですが。
せっかくの純オブジェクト指向言語ですから、クラスの作り方をば。
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
などと記述しているのは無駄すぎます。そこで、上記のような定義を行うことを請け負ってくれるメソッドがあります。
n = method()のように書ける。そのようなメソッドを関数と呼び習わす。
プログラミング言語/Ruby/RubyToolLibrary