Ruby基礎文法ひとめぐり
はじめに
やっぱり日本人ならRubyをやっとくべきかなと思いとりあえずひとめぐりしてみることにした。文法がGroovyに似ていることもありこれまで "わかったつもり" でいたのを払拭していきたいと思います。
変数の種類と変数名
Rubyは先頭の1文字によって変数の種類が変わる。
foo #=> ローカル変数 @foo #=> インスタンス変数(@) @@foo #=> クラス変数(@@) $foo #=> グローバル変数($) FOO #=> 定数(大文字から始まる)
(*)
数値にはアンダーバー区切りが使える
Rubyでは数値を表すときにアンダーバーが使える。これはよく3桁区切りで数値をカンマ区切りで表現するのに似せてある。
例えば、
print(3_420_500)
とすると
3420500
インクリメント、デクリメント
Rubyには++がない。だから代わりに+=や-=を使うんだ。
例) >> num = 1 => 1 >> num += 1 => 2 >> num -= 1 => 1
(*)
文字列
Rubyの文字列はシングルクォートでもダブルクォートでもどちらもで使える。
>> str = 'abc' => "abc" >> str = "abc" => "abc"
ダブルクォートを使うと、#{ } を使って式を展開した結果を文字列とすることができる。
>> list = ['abc', 'def', 'ghi'] => ["abc", "def", "ghi"] >> str2 = ">>> #{list.map{|s| s.capitalize}.join(',')} <<<" => ">>> Abc,Def,Ghi <<<"
(*)
RubyではGroovyと違って /文字列/ の形式はきっちり正規表現のクラスとして表現されているようだな。
>> 'abc'.class => String >> "abc".class => String >> /abc/.class => Regexp <<
(*)
文字列操作
文字列操作色々。
結合
>> str1 = "aaa" + "bbb" => "aaabbb" >> str2 = ["aaa", "bbb", "ccc"].join("-") => "aaa-bbb-ccc"
分割
>> record = "aaa,bbb,ccc".split(/,/) # Regexp型 => ["aaa", "bbb", "ccc"] >> record = "aaa,bbb,ccc".split(",") # splitは引数が文字列でもOKみたい => ["aaa", "bbb", "ccc"]
長さ
>> "abc".length => 3 >> "abc".size => 3
lengthでもsizeでもどちらでもOK。ここらへんはGroovyと同じですね。
切り出し
>> "abcd"[0, 2] => "ab"
検索
>> "abcd".index(/bc/) => 1
配列
宣言
Rubyの配列は [ ] を使って宣言する。
>> ary1 = [100, 200, 300] => [100, 200, 300] >> ary1[0] => 100 >> ary1[2] => 300
型が違ってもOK
>> ary = [100, "aaa", {"key" => "value"}] => [100, "aaa", {"key"=>"value"}]
長さ
配列の長さもlength, sizeどちらでもいいようだ。
>> ary = [100, "aaa", {"key" => "value"}] => [100, "aaa", {"key"=>"value"}] >> ary.length => 3 >> ary.size => 3
配列操作あれこれ
先頭を取り出す
>> ary.shift => 100 >> ary => ["aaa", {"key"=>"value"}] # 元の要素に破壊的に働く
先頭に要素の追加はunshift
>> ary.unshift(5) => [5, "aaa", {"key"=>"value"}]
末尾要素を取り出す
>> ary.pop => {"key"=>"value"} >> ary => [5, "aaa"] # 元の要素に破壊的に働く
末尾に要素を追加
>> ary.push(9) => [5, "aaa", 9]
ハッシュ
ハッシュ操作あれこれ。
宣言
ハッシュは { } で囲み、キー => 値 の形でキーバリューを書き、カンマで区切る。
>> hash = {"a" => 1, "b" => 2, "c" => 3} => {"a"=>1, "b"=>2, "c"=>3}
キーはシンボルを使うのが一般的なんだって。
シンボルってのは :a みたいに コロン+英字ってなってるやつ。
>> hash2 = {:a => 1, :b => 2, :c => 3} => {:b=>2, :a=>1, :c=>3}
値の取り出し
>> hash["a"] => 1 >> hash2[:a] => 1
Groovyみたく、「.キー名」では取り出せない。
>> hash.a NoMethodError: undefined method `a' for {"a"=>1, "b"=>2, "c"=>3}:Hash from (irb):153 from :0
値の代入
>> hash["d"] = 4 => 4 >> hash2[:d] = 4 => 4 >> hash => {"a"=>1, "b"=>2, "c"=>3, "d"=>4} >> hash2 => {:d=>4, :b=>2, :a=>1, :c=>3}
キー一覧
>> hash => {"a"=>1, "b"=>2, "c"=>3, "d"=>4} >> hash2 => {:d=>4, :b=>2, :a=>1, :c=>3} >|ruby| >> hash.keys => ["a", "b", "c", "d"]
値一覧
>> hash.values => [1, 2, 3, 4]
キーの存在チェック
>> hash.key?("a") => true >> hash.key?("e") => false
ループ
ループいろいろ。
Array#eachでループ
Array#each >> [1, 2, 3].each { |i| ?> puts i >> } 1 2 3 => [1, 2, 3]
※ each do |i| ... end でもOK
Integer#timesでループ
>> 5.times do |i| puts i end 0 1 2 3 4 => 5
集合操作
Enumerableに定義されている集合操作をいくつか試してみる。
条件に合致するものを選択する(select)
>> [1, 2, 3, 4, 5].select{|x| x.even?} => [2, 4]
条件に合致するものを除外する(reject)
>> [1, 2, 3, 4, 5].reject{|x| x.even?} => [1, 3, 5]
条件に合致する最初のものを返す(detect)
>> [1, 2, 3, 4, 5].detect{|x| x.even?} => 2
クロージャ (2011-04-11追記)
Rubyでクロージャを使いたい場合はlambdaを使えばいいみたい。
irb(main):012:0> clos = lambda do |x| # 二乗するクロージャを宣言 irb(main):013:1* x * x irb(main):014:1> end => #<Proc:0x000001009822f8@(irb):12 (lambda)> irb(main):015:0> clos(10) #呼び出しは.callとする必要があるみたい… NoMethodError: undefined method `clos' for main:Object from (irb):15 from /opt/local/bin/irb1.9:12:in `<main>' irb(main):016:0> puts clos(10) NoMethodError: undefined method `clos' for main:Object from (irb):16 from /opt/local/bin/irb1.9:12:in `<main>' irb(main):017:0> puts clos.call(10) #できた 100 => nil irb(main):018:0> puts clos.call(100) #できた 10000 => nil
参考: Rubyの「クロージャ」再考 - バリケンのRuby日記 - Rubyist
v1.9系からはlambdaの宣言に新しい記法が追加されたとのこと。
irb(main):006:0> clos = ->(x, y) { x + y } => #<Proc:0x00000100934e90@(irb):6 (lambda)> irb(main):007:0> puts clos.call(10, 20) 30 => nil
- >と(x,y)の間にスペースが入ってるとダメでした。