1. ホーム
  2. スクリプト・コラム
  3. ルビートピックス

Rubyでコレクションを書くためのガイド

2022-02-03 05:11:24

配列やハッシュは、(コンストラクタに引数を渡す必要がない限り)リテラルで表現することをお勧めします。

  # bad
  arr = Array.new
  hash = Hash.new

  # good
  arr = []
  hash = {}



    単語の配列(スペースや特殊記号を含まない)が必要な場合は、常に %w を使って文字列の配列を定義してください。このルールは、2つ以上の配列にのみ適用してください。

  # bad
  STATES = ['draft', 'open', 'closed']

  # good
  STATES = %w(draft open closed)



    符号付き配列が必要な場合(Ruby 1.9 との互換性を維持する必要がない場合)には %i を使用します。

  # bad
  STATES = [:draft, :open, :closed]

  # good
  STATES = %i(draft open closed)



    ArrayやHashの最後のエントリの後にカンマを付けないようにしましょう。特に、これらのエントリが1行にない場合は注意が必要です。

  # bad - easier to move/add/remove items, but still not preferred
  VALUES = [
        1001,
        2020,
        3333,
       bad]

  # bad
  VALUES = [1001, 2020, 3333, ]

  # good
  VALUES = [1001, 2020, 3333]



    配列に巨大な区間を作らないようにする。

  arr = []
  arr[100] = 1 # now you have an array with lots of nils



    配列の最初と最後の要素にアクセスするときは、[0] や [-1] の代わりに、first または last を使用するのが好ましいです。

    要素が一意であることを保証したい場合は、Array の代わりに Set を使用します。Setは、配列のような一貫性保持操作やハッシュ化された高速検索が可能で、順不同で一意な要素を持つ集合に適しています。

    ハッシュキーは可能な限り文字列ではなく、シンボルを使用する。

  # bad
  hash = { 'one' => 1, 'two' => 2, 'three' => 3 }

  # good
  hash = { one: 1, two: 2, three: 3 }



    ハッシュのキーに揮発性のオブジェクトを使用しないようにする。

    ハッシュキーがシンボルの場合、1.9の新しいハッシュ構文を使用することをお勧めします。

  # bad
  hash = { :one => 1, :two => 2, :three => 3 }

  # good
  hash = { one: 1, two: 2, three: 3 }



    Ruby 1.9のハッシュ構文と、同じハッシュリテラル内の矢印の形のハッシュを混在させないでください。
    シンボルでないキーを取得した場合、矢印構文に変換します。

  # bad
  { a: 1, 'b' => 2 }

  # good
  { :a => 1, 'b' => 2 }



    Hash#key? で Hash#has_key なし、Hash#value? で Hash#has_value なしですか?Matz氏は、長すぎる形式は非推奨とする方向で検討されていると述べています。

  # bad
  hash.has_key?(:test)
  hash.has_value?(value)

  # good
  hash.key?(:test)
  hash.value?(value)



    存在するはずのハッシュ・キーを扱うときは、フェッチを使用します。

  heroes = { batman: 'Bruce Wayne', superman: 'Clark Kent' }
  # bad - if we make a mistake we might not spot it right away
  heroes[:batman] # => "Bruce Wayne"
  heroes[:supermann] # => nil

  # good - fetch raises a KeyError making the problem obvious
  heroes.fetch(:supermann)



    fetchを使用する場合、カスタムロジックを使用するのではなく、第2引数を使用してデフォルト値を設定します。

  batman = { name: 'Bruce Wayne', is_evil: false }

  # bad - if we just use || operator with falsy value we won't get the expected result
  batman[:is_evil] || true # => true

  # good - fetch work correctly with falsy values
  batman.fetch(:is_evil, true) # => false



    デフォルト値を直接設定するのではなく、フェッチを使ってブロックを追加するようにしてください。

  batman = { name: 'Bruce Wayne' }

  # bad - if we use the default value, we eager evaluate it
  # so it can slow the program down if done multiple times
  batman.fetch(:powers, get_batman_powers) # get_batman_powers is an expensive call

  # good - blocks are lazy evaluated, so only triggered in case of KeyError exception
  batman.fetch(:powers) { get_batman_powers }



    ハッシュから連続して値を取得する必要がある場合は、Hash#values_at を使用します。

  # bad
  email = data['email']
  nickname = data['nickname']

  # good
  email, username = data.values_at('email', 'nickname')



    Ruby 1.9では、ハッシュはもはや順不同に振る舞うことはないことを覚えておいてください。(訳者注:Ruby 1.9では、要素が挿入された順番を記憶するようになります。)

    コレクションをトラバースするときは、コレクションを変更しないでください。