便利なRubyイディオム

  • 494
    いいね
  • 0
    コメント

「Rubyならこう書く」あれこれ

  • Arrayオブジェクト
  • Rangeオブジェクト
  • ブロックとProcオブジェクト
  • シンボルとハッシュ
  • クラスとコンストラクタ

(追記)
ブロックとProcオブジェクトについては、長くなったので以下に分離しました。

[Ruby基礎] ブロックとProcをちゃんと理解する
http://qiita.com/kidachi_/items/15cfee9ec66804c3afd2

配列(Array)

要素の操作


#配列要素の分割
> "foo bar bazz".split
=> ["foo", "bar", "bazz"]

#配列要素の指定文字列での分割
> "fooxbarxxxxbazz".split('x')
=> ["foo", "bar", "", "", "", "bazz"]

#配列要素の順番入れ替え
> "foo bar bazz".split.reverse
=> ["bazz", "bar", "foo"]

#配列要素の順番入れ替え
> a = "foo bar bazz".split.shuffle
=> ["bar", "foo", "bazz"]

要素の追加

#配列要素の追加
> a.push(8)
=> ["bar", "foo", "bazz", 8]

#配列要素の追加2
> a << 10
=> ["bar", "foo", "bazz", 8, 10]

#配列要素の追加3(chain)
> a << 'fuga' << 'moga'
=> ["bar", "foo", "bazz", 8, 10, "fuga", "moga"]

#配列要素の結合
> a.join
=> "barfoobazz810fugamoga"

#配列要素の結合2
> a.join(', ')
=> "bar, foo, bazz, 8, 10, fuga, moga"

範囲(Range)

範囲から配列生成

#「.」2つで後方の要素(9)を含む
> (0..9).to_a
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

#「.」3つで後方の要素(9)は含まない
> (0...9).to_a
=> [0, 1, 2, 3, 4, 5, 6, 7, 8]

配列要素を範囲で指定して取得

#文字列を配列に変換
> b = %w[foo bar baz fuga moga]
=> ["foo", "bar", "baz", "fuga", "moga"]

#配列から指定範囲を取り出す
> b[0..2]
=> ["foo", "bar", "baz"]

配列要素を範囲で指定して取得2

#配列へ変換
> c = (0..9).to_a
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

#配列の最後の要素指定
> c[5..(c.length-1)]
=> [5, 6, 7, 8, 9]

#配列の最後の要素指定2
> c[5..-1]
=> [5, 6, 7, 8, 9]

その他

#範囲は文字列に対しても利用出来る
> ('a'..'e').to_a
=> ["a", "b", "c", "d", "e"]

ブロック

分かりづらかったので少し丁寧に。

  • ブロックとは何か
  • yield、Procとは何か
  • Proc補足
  • で、ブロックやProcって何が嬉しいの?

の順でいきます。

(追記)
本項は以下を参照。

[Ruby基礎] ブロックとProcをちゃんと理解する
http://qiita.com/kidachi_/items/15cfee9ec66804c3afd2

シンボル

文字列と近いが、少々性質が異なる。
内部的な比較の際、文字列は1文字ずつ比べる必要があるが、
シンボルは一度に全体を比較可能。
→ハッシュ等のキーとして理想的な性質。

#文字列は分割できる
>> "name".split('')
=> ["n", "a", "m", "e"]
#シンボルは分割できない
>> :name.split('')
NoMethodError: undefined method `split' for :name:Symbol

#文字列は(分割して)reverseできる
>> "foobar".reverse
=> "raboof"
#シンボルは(分割して)reverseできない
>> :foobar.reverse
NoMethodError: undefined method `reverse' for :foobar:Symbol

Ruby 1.9以降では、シンボルをキーとして扱う場合の特別な記法をサポート。
以下の二つは同義。

{ :hoge => 'hoge', :fuga => 'fuga'}
{ hoge: 'hoge', fuga: 'fuga'}

よって以下二つも同義。

>> h1 = { :name => "hogefuga", :email => "foo@example.com" }
=> {:name=>"hogefuga", :email=>"foo@example.com"}

>> h2 = { name: "hogefuga", email: "foo@example.com" }
=> {:name=>"hogefuga", :email=>"foo@example.com"}

>> h1 == h2
=> true

ハッシュがよりスムーズに記述できる。

ハッシュをブロックに渡す

>> hash = { success: "It worked!", error: "It failed." }
=> {:success=>"It worked!", :error=>"It failed."}

>> hash.each do |key, value|
>>   puts "Key #{key.inspect} has value #{value.inspect}"
>> end
Key :success has value "It worked!"
Key :error has value "It failed."

→ブロックにはkeyとvalueの二つが渡ることになる。

※inspectはオブジェクトを可視化して返す
inspectを用いない場合、

>> hash.each do |key, value|
>>   puts "Key #{key} has value #{value}"
>> end
Key success has value It worked!
Key error has value It failed.

こうなる。

Railsに現れるRuby

上のハッシュの知識をもとに、Rails内で使うRubyの記述を読み解いてみる。

cssを出力するタグの例

<%= stylesheet_link_tag "application", media: "all",
                                       "data-turbolinks-track" => true %>

いくつか特徴がある。

  1. メソッド呼び出しの丸かっこは省略可能。 →以下は同義
stylesheet_link_tag("application", media: "all",
                                   "data-turbolinks-track" => true)
stylesheet_link_tag "application", media: "all",
                                   "data-turbolinks-track" => true
  1. 最後の引数がハッシュの場合、波括弧は省略可能。 →以下は同義
stylesheet_link_tag "application", { media: "all",
                                     "data-turbolinks-track" => true }
stylesheet_link_tag "application", media: "all",
                                   "data-turbolinks-track" => true
  1. シンボルではハイフンを使用できない (mediaは「media:」という新式の記法なのに、data-turbolinks-trackは 「"data-turbolinks-track" =>」という旧式記法である理由)
data-turbolinks-track: true  #NG。シンボルではハイフンを使用できない
"data-turbolinks-track" => true  #OK

結果、出力されるタグ

<link data-turbolinks-track="true" href="/assets/application.css" media="all" rel="stylesheet" />

クラスとコンストラクタ

String

>> a = "hoge"
=> "hoge"

#明示的な書き方
>> a = String.new("hoge")
=> "hoge"

Array

>> a = [1, 3, 2]
=> [1, 3, 2]

#明示的な書き方
>> a = Array.new([1, 3, 2])
=> [1, 3, 2]

Hash => コンストラクタが特殊

hashのコンストラクタに値を渡した場合、
「キーが存在しない場合に返されるデフォルト値」として定義される。

# 何も値を渡さずに初期化
>> h = Hash.new
=> {}
>> h[:foo]            # 存在しないキー :foo
=> nil  # キーが存在しない場合のデフォルト値はnil

# 値を渡して初期化
>> h = Hash.new(0)    # デフォルト値をnilから0に変更
=> {}
>> h[:foo]
=> 0    # キーが存在しない場合のデフォルト値は0

Module

module ApplicationHelper

通常(生のRuby)では、moduleはincludeを使い呼び出す(MixidIn)ことができる。

が、Railsは自動で呼び出してくれるため、定義さえすれば全てのViewで利用することが出来る。

もう一歩踏み込むならこちら

[Ruby] 便利な組み込みクラスのメソッド達
Enumerable編
http://qiita.com/kidachi_/items/a00558cfb0a6a3e23f4b
Array編
http://qiita.com/kidachi_/items/e9cb26c4e6cb36b70a1c
Hash編
http://qiita.com/kidachi_/items/651b5b5580be40ad047e
String編
http://qiita.com/kidachi_/items/7b355eb355b2d1390cf5

以下に続く

[Ruby基礎] ブロックとProcをちゃんと理解する
http://qiita.com/kidachi_/items/15cfee9ec66804c3afd2