問題

私はerbライブラリで次のコードを見つけました。 double (( ))に注意してください:

 class MyTest
  def location=((filename, lineno))
    @filename = filename
    @lineno = lineno if lineno
  end
end
 

次のlocatia=メソッドは、テスト用の(( ))を持たない別のバージョンです。

 class MyTest    
  def locatia=(filename, lineno)
    @filename = filename
    @lineno = lineno if lineno
  end
end
 

私はこの結果を得た:

 a = MyTest.new
a.location = "foo", 34
a # => #<MyTest:0x2a2e428 @filename="foo", @lineno=34>

b = MyTest.new
b.location = "foo"
b # => #<MyTest:0x2a2e338 @filename="foo">

c = MyTest.new
c.locatia = "foo", 34
c # >> `locatia=': wrong number of arguments (given 1, expected 2) (ArgumentError)
 

doubleかっこのバージョンは正常に動作します。単一のものは失敗します。ソースコードのあるレベルで指定する必要があります。すべての手がかりは?

  ベストアンサー

破壊だ

location=は1つのパラメータを受け入れます。このパラメータは配列とみなされ、配列の最初の要素がfilenameに、2番目の要素がlinenoになるように破壊されます。外側の括弧は、メソッド定義の通常の(通常はオプションの)括弧です。内側の括弧は、最初の(および唯一の)パラメータの構造を示します。

仕事での破壊の別の例を次に示します。

 { foo: 17, bar: 34 }.each.with_index { |(key, value), index|
  p [key, value, index]
}
# => [:foo, 17, 0]
#    [:bar, 34, 1]
 

Hash#eachはペア[key, value]を生成します。 Enumerator#with_index[value, index]のペアを生成します。それらを両方適用し、[[key, value], index]をブロックに渡します。私たちはこれを行うことができます:

 { foo: 17, bar: 34 }.each.with_index { |pair, index|
  key = pair[0]
  value = pair[1]
  p [key, value, index]
}
 

しかし、それは破壊的にはるかに簡単です。 single-rvalue配列は自動的にマルチ値の割り当てで破壊されるため、(key, value) = pair(またはkey, value = pair)を別の例として書くこともできます。

  同じタグがついた質問を見る

rubymethodsparameters