|| =は、共通のRubyイディオムです。これは、まだ設定されていない場合にのみ値を割り当てます。効果がオーバーライドされない===、
if some_variable == nil
some_variable = some_value
end
又は
some_variable= some_value unless some_variable
ようなコードと同じであり、同一のための2つのオブジェクトを比較します。 Hash === args.last
の場合、Class型のオブジェクトであるHashはargs配列の最後の項目のクラスと一致するかどうかをチェックします。このコードでは、クラス#===の実装が比較対象のクラスのチェックを強制するという明らかな事実を利用しています。
これは、例えば、周囲の他の方法は動作しない。
a = [{}]
Hash === a.last #=> true
a.last === Hash #=> false
方法の後続の引数は{}
を提供しなくても、ハッシュのコンテンツとして供給することができますしたがって、これを行うことができます:
def hello(arg1, arg2, arg3)
puts [arg1.class, arg2.class, arg3.class].join(',')
end
hello 1,2,3 #=> Fixnum,Fixnum,Fixnum
hello :a, "b", :c => 1, :d => 99 #=> Symbol,String,Hash
これは、オプションのパラメータの可変長リストを関数に提供するためによく使用されます。
元のコードを正確にbtw書き換えてもよろしいですか?引数の配列を取得するには、通常、宣言されているように引数に*を追加します。そうでなければ、オブジェクトを無効にする場合はargsを配列として入力する必要があります。
def add_spec_path_to(*args) # now args is an array
args << {} unless Hash === args.last # if trailing arguments cannot be
# interpreted as a Hash, add an empty
# Hash here so that following code will
# not fail
args.last[:spec_path] ||= caller(0)[2] # Set the spec_path option if it's not
# already set
end
EDIT:*引数の事でさらに拡大し、これを試してみてください。
def x(*args)
puts args.join(',')
puts args.map{|a| a.class }.join(',')
end
x 1,2,:a=>5,:b=>6
1,2,a5b6
Fixnum,Fixnum,Hash
... *引数を使用すると、引数が配列としてメソッドに提示されます。私は、例えば、次のように、*を使用しない場合:
def y(args)
puts args.join(',')
puts args.map{|a| a.class }.join(',')
end
を...そしてargsが、私はメソッドを呼び出す前に、配列である必要があり、または私が「例外ArgumentError取得します:の間違った番号を一つの事を除いて何かのための "議論"を渡しただから、このようにしなければなりません:
... {}で明示的に作成されたハッシュを使用しています。そしてそれは醜いです。
上記の全ては、MRI 1.8.6、btwで試験した。少し短いように
はありません、配列に渡すと、理にかなっています。 – rampion
私は理解していません。some_method([arg1、arg2、arg3]、options_hash)のようにメソッドを呼び出しますか?それは恐ろしいです:上記の編集された答えを参照してください... –
素晴らしい説明、マイク。 –