Rubyはプログラム言語であり、まつもと ゆきひろ氏が開発をされているフリーソフトウェアです。ライセンスはGPLライセンスになっています。従って、商用での無償利用が可能です。
今、非常にRubyが注目されています。
Rubyにはいくつか特筆すべき特徴があります。
- 非常に可読性の高い文法であり、習得しやすい
- Ruby自体の開発やライブラリの開発者が世界中にいて、活発に開発が行われている
- 日本人が作った言語であるため、Ruby自体に関する日本語での情報が非常に多く存在する
- 多くの都道府県でRubyを活用することを推奨する動きがある
- 現在最も多く行われているWebアプリケーションの開発の多くのフェーズは「テキスト処理」であるため利用に適している
これらの特徴から、個人的には最初に習得するプログラミング言語として最もお勧めです。
では、実際にRubyに触れてみたいと思います。 Rubyにはirbという「対話型コンソール」があります。「対話」とは何かを、体感することから始めましょう。
コンソールでirbと入力して、起動してみて下さい。
>
となっていると思います。 では、定番「Hellow, world」から。
> puts "Hellow, World!"
Hellow, World!
=> nil
となったかと思います。おめでとう御座います、Rubyに入門されました。
Rubyはインタプリタ、つまり実行する時にプログラムがコンパイルされてコンピューターが処理を行える状態にするという流れで動きます。このirbは公用語が「ruby」で話し相手がコンピューターという世界です。つまり「>」はコンピューターが人間からRubyで話しかけられるのを待っている状態です。そこへ1行目では「puts "~"」と話しかけています。Rubyは言葉を解釈し実行ます。2行目はその実行結果です。3行目はコンピューターからの返答になり、今回は「nil」つまり何も返す言葉は無いよと言ってきております。
- コンピューターと人間との間では、
- 入力
- 処理
- 出力
という流れで情報のやり取りが行われます。
irbでは「>」はコンピューターが人間からの入力を待っている状態をさし、Rubyという言葉で指示された内容を処理します。その処理の中で、画面に表示するというものがあった場合は、画面に表示等が行われます。最後にはコンピューターから返答が返ってきます。コンピューターは割と素っ気ない正確なので特に終わったよとは言わず「nil」つまり空っぽと返答してくることがあります。素っ気ない正確なので気にしないで下さい。
では、引き続きRubyの文法とRubyのセンテンスを学んで行きましょう。
あまり重要では無いのですがRubyは「オブジェクト指向」という考え方を採用 しているプログラミング言語です。以下は、オブジェクト指向であるのを体感 する為のサンプルです。
> 4
=> 4
> 10
=> 10
> 10.class
=> Fixnum
> 10+10
=> 20
5行目の「10.class」というのが特徴的な部分です。これはコンピューターに対して「1 0というのは、どんなクラスなの?」と聞いていて、次の行では「Fixnum」だよ と返してきています。
また、こちらも実行してみて下さい。
> 10.methods
=> [:to_s, :-@, :+, :-, :*, :/, :div, ・・・・
これは、コンピューターに「10で使える機能(メソッド)を教えて」と問い合わせた結果が表示されます。大量の機能が始めから備わっていることが確認できます。
このように、オブジェクト指向のプログラムでは 最初から備わっている機能を動かし思い通りの結果を得られるように呼び出す内容を定義する ということになります。もちろん、備わっている機能を幾つか組み合わせて新しい機能を作成することもできます。
次は判定です。
> x = 10
=> 10
> x < 5
=> false
> x > 5
=> true
> x == 10
=> true
1行目では変数を使っています。変数xに10という数字を代入します。3行目では「変数xは5より小さい?」と問い合わせを行い、コンピューターからは「false」つまり「いいえ」と返ってきています。Rubyでは「はい」は「true」で「いいえ」は「false」です。5行目「変数xは5より大きい?」については「true」と返ってきています。7行目は「変数xは10と同じですか?」という問い合わせです。「=」は1つだと変数への代入となり、2つだと中身の確認で使えます。
> x = 10
=> 10
> if x < 5
?> puts "x is smaller than 5."
?> end
=> nil
このサンプルでは、まず変数xに10を代入しています。 次に、「if」というRubyの機能を使い、「変数xが5より小さい時には・・・」という状況に応じて処理を変更することを、コンピューターに伝えています。「5より小さい」時は、4行目が実行されます。5行目の「end」は条件に合致した場合に行う処理はここまでですよ、とコンピューターへ伝えています。最後に6行目で「=>nil」と返ってきていますので、コンピューターは指示された内容を作業したけども、特に返信することは無かったと伝えています。では、もう1つのパターンを見てみます。
> if x > 5
?> puts "x is bigger than 5."
?> end
x is bigger than 5.
=> nil
このサンプルでは、先ほど違い条件を「5より大きい場合」としています。変 数xには10が代入されているので、条件に合致します。その結果、4行目にて 「x is bigger than 5.」という処理結果が発生しています。
Rubyには面白い機能があります。ifの反対の意味である「unless」という機能 がその1つです。「unless」は「もし、~ではないなら」という否定です。
> unless x < 5
?> puts "x is not smaller than 5."
?> end
x is not smaller than 5.
xは10なので、5より小さくありません。その結果、条件にマッチするので処理 が実施されています。
さて、備わっている機能を使ってみましたが、そろそろ自分で機能を作ってみましょう。とはいうものの、機能を作るということは厳密には ある機能と違う機能をどのような順番で処理させるかを決めること という感じです。
では、具体的に見て行きます。
> def plus_two(num)
?> num += 2
?> end
=> nil
以上は「plus_two」という名前の機能を定義(define)しています。コンピューターに「plus_twoと言われたら、こんなことを処理してね」と教えています。plus_twoは数字を受け取り、2を加算してくれます。
では、実際にこの機能を使ってみます。
> plus_two(10)
=> 12
「plus_twoに数字の10」とコンピューターに伝えたところ、返答は「12」でした。10に2が加わっています。このplus_twoという機能な、ここでコンピューターに教えた機能なので、ここでしか実行することができません。
ここで少し意地悪をしてみましょう。この機能は数字を伝えられる前提で作られています。もし「文字」が伝えられるとどうなるでしょうか?
> plus_two("ten")
TypeError: can't convert Fixnum into String
from (irb):35:in `+'
from (irb):35:in `plus_two'
from (irb):38
from
/Users/yuya_lush/.rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in
`<main>'
ということで「TypeError」というものが書かれています。つまり、「機能は数字を期待しているけど、期待されているものに合って無いよ!」とコンピューターがエラーを起こしたことを伝えてきています。
もう一つ、サンプルを。
> plus_two("10")
TypeError: can't convert Fixnum into String
from (irb):35:in `+'
from (irb):35:in `plus_two'
from (irb):39
from /Users/yuya_lush/.rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `<main>'
今度は数字の10ではなく、文字の「10」を渡しました。これもエラーです。人間は数字と文字の区別を自然と行いますが、コンピューターは数字と文字では大違いなので、正確に伝えて欲しいと文句を言います。では、怒られないように文字を数字に変換する機能を使ってみます。
> plus_two("10".to_i)
=> 12
はい。エラーは起きません。「"10".to_i」というのは、文字である10が持つ、数字に変換する機能を使って「"10"」から「10」に変身させています。そして、変身後の姿である数字の10がplus_twoという機能で使われるので期待通りに動いてくれています。
ここまでは変数に数字を1つ代入し、その変数を使って判定をさせてみたり、新しい機能を自分で作ってみたりしました。
実際に現実社会で使えるものを作る場合、たくさんのデータを処理しないといけません。変数に1つ1つ数字や文字を保存していたのでは、処理を書きにくいです。そこで、複数の数字や文字を処理するときに使うと便利は配列とハッシュをみていきましょう。
まずは配列です。以下のサンプルを見てみましょう。
> numbers = [1, 3, 5, 7]
=> [1, 3, 5, 7]
> numbers.length
=> 4
> words = ["one", "three", "five", "seven", "nine"]
=> ["one", "three", "five", "seven", "nine"]
> words.length
=> 5
「=」を使い変数numbersに代入をしていますが、書き方が特殊です。「[... ,... , ... ]」という書き方をすると複数の数字や文字を変数に代入することができます。
配列の中には、なんでも保存することが可能です。このサンプルでは数字と文字を保存していますが、それ以外にも配列の中に変数を入れることもできますし、配列の中に配列をいれることも可能です。
> arr = [ x, y ]
=> [10, 20]
> arr[0]
=> 10
> arr_arr = [arr]
=> [[10, 20]]
変数numbersに保存されている配列の中には4つの数字が保存されていますが、それぞれに対して直接アクセスすることもできますし、全体にもアクセスすることができます。
> numbers
=> [1, 3, 5, 7]
> numbers[0]
=> 1
> numbers[0..2]
=> [1, 3, 5]
> numbers[0] + numbers[3]
=> 8
> numbers[100]
=> nil
このサンプルでは、まず1行目でnumbersの中身を確認しています。 次に、3行目では「numbersの0番目の中身」を指定しています。配列の中は0から始まり1つづ増えて行く数字で位置を指示することができます。したがって
- 0番目 1
- 1番目 3
- 2番目 5
- 3番目 7
と保存されています。
5行目では、「変数numbersの0番目から2番目まで」という 範囲 を指定しています。その為、「1と3と5」と返答されています。7行目は直接中身を利用してしまうサンプルです。0番目と3番目つまり、1と7をたし算しますので結果は「8」が返ってきています。10行目は中身がない位置を指定するとどうなるかというサンプルです。何も無いので、「nil」つまり「空っぽ」と返答されています。
次はハッシュです。
ハッシュはPythonという言語では「ディクショナリ(辞書)」と呼ばれるものです。辞書は「見出し」と「説明」で構成されています。配列と似ていますが、ハッシュでは文字を使って指定することができるのが特徴です。
> dic = { "a" => 1, "b" => 2, "c" => 3}
=> {"a"=>1, "b"=>2, "c"=>3}
> dic["a"]
=> 1
> dic["b"]
=> 2
1行目でハッシュを代入しています。「{ "キー" => 値 , "キー" => 値 }」というのが文法です。3行目と5行目では、キーを使って値にアクセスしています。ハッシュは他の書き方もできます。
> dic2 = {:a => 10, :b =>20}
=> {:a=>10, :b=>20}
> dic2[:a]
=> 10
「"キー"」ではなく、この例では シンボル という書き方をしています。基本的には同じ物と考えて下さい。文字で書くと"を2回入力しますが、シンボルだと:を1回なので便利です。ハッシュの時に使うキーではシンボルで書くと便利・・・と覚えておきましょう。
なお、ハッシュのキーには数字や文字、このようなシンボルなどを利用するこ とができます。
さて、ここまで色々と見てきましたが、最後に配列を活用する 繰り返し処理 を見て行きます。
データベースから何件かのデータを取得し、受け取ったデータを繰り返し処理して行く・・・というケースがあります。まずは、サンプルから。
> a = [1, 3, 5, 7]
=> [1, 3, 5, 7]
> a.each do |num|
?> puts num
?> end
1
3
5
7
=> [1, 3, 5, 7]
このサンプルでは1行目で1、3、5、7という4つの数字を配列にして、変数aに代入しています。3行目では「変数aに保存されているそれぞれの要素を1つずつ取り出し、変数numに入れて」と処理を伝えています。変数numに変数aに保存されている配列から取り出された要素が渡され、4行目にて中身を表示するという処理が行われます。そのため、1、3、5、7と順番に表示が行われている・・・というものです。
ここでのポイントは、私たちは「それぞれ(each)」と言うだけで処理が行われているという点です。つまり、配列aの中身がいくつであってもコンピューターが勝手に全部の要素に対して処理をしてくれます。
Rubyの1つの特徴は、こういった簡潔な記述ができる点にあります。
なお、「取り出したものへの処理」つまり、do ~ endまでの処理のことを ブロック と言います。ブロックには二つの書き方があります。
> a.each do |i| puts i end
1
3
5
7
=> [1, 3, 5, 7]
> a.each {|i| puts i}
1
3
5
7
do ... endで書く書き方と{ ... }で書く書き方があります。do - endは処理が複数行に渡る長い場合に使い、 {}は1行で終わる時に使うのが慣習ですが、結果は同じになります。