rubyのsendメソッドに慣れてきたのですが、なぜかこんなことができません
a = 4
a.send(:+=, 1)
何らかの理由でこれは機能しません。それから私は次のようなことを試しました
a.send(:=, a.send(:+, 1))
しかし、これもうまくいきません。「送信」を介してプラスイコールを起動する適切な方法は何ですか?
rubyのsendメソッドに慣れてきたのですが、なぜかこんなことができません
a = 4
a.send(:+=, 1)
何らかの理由でこれは機能しません。それから私は次のようなことを試しました
a.send(:=, a.send(:+, 1))
しかし、これもうまくいきません。「送信」を介してプラスイコールを起動する適切な方法は何ですか?
基本的なオプションは次のとおりだと思います。
a = a.send(:+, 1)
これは、send
オブジェクトへのメッセージのためです。割り当ては、オブジェクトではなく変数を変更します。
いくつかのメタプログラミングを使用して変数に直接割り当てることは可能ですが、コードは複雑です。これまでのところ、私が見つけることができる最高のものは次のとおりです。
a = 1
var_name = :a
eval "#{var_name} = #{var_name}.send(:+, 1)"
puts a # 2
またはインスタンス変数を使用します。
@a = 2
var_name = :@a
instance_variable_set( var_name, instance_variable_get( var_name ).send(:+, 1) )
puts @a # 3
以下を参照してください。
p 4.respond_to?(:"+=") # false
p 4.respond_to?(:"=") # false
p 4.respond_to?(:"+") # true
a+=1
のシンタックスシュガーですa = a+1
。しかし、直接的な方法はありません+=
。=
メソッドではなく代入演算子です。一方Object#send
、引数としてメソッド名を取ります。したがって、あなたのコードは、あなたが探している方法では機能しません。
=
Rubyにはメソッドがないからです。Ruby=
では C/C++ のようには機能しませんが、変数に新しい値を割り当てるのではなく、新しいオブジェクト参照を変数に割り当てます。
これは少し的外れかもしれませんが、私はこれa
を実際にオブジェクトで動的に呼び出されるメソッドで行おうとしていました。たとえば、added_count
and updated_count
for のような属性を使用しImporter
て、次のように書きました
class Importer
attr_accessor :added_count, :updated_count
def increment(method)
send("#{method}=", (send(method) + 1))
end
end
だから私は使用することができimporter.increment(:added_count)
ますimporter.increment(:updated_count)
これら 2 つの異なるカウンターしかない場合、これはばかげているように見えるかもしれませんが、場合によっては、半ダース以上のカウンターと、attr を増加させるさまざまな条件があるため、便利です。