我熟悉ruby发送方法,但由于某种原因,我不能做这样的事情
a = 4
a.send(:+=, 1)
出于某种原因,这不起作用。然后我尝试了类似
的东西a.send(:=, a.send(:+, 1))
但这也行不通。通过'发送'解雇加上等于的正确方法是什么?
答案 0 :(得分:6)
我认为基本选项只是:
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
答案 1 :(得分:1)
见下文:
p 4.respond_to?(:"+=") # false
p 4.respond_to?(:"=") # false
p 4.respond_to?(:"+") # true
a+=1
是a = a+1
的句法糖。但是没有直接的方法+=
。 =
是赋值运算符,也不是方法。另一方面,Object#send
将方法名称作为其参数。因此,您的代码将无法正常工作。
答案 2 :(得分:0)
这是因为Ruby没有=
方法。在Ruby =
中,它不像在C / C ++中那样工作,而是将新的对象引用分配给变量,而不是为变量赋值。
答案 3 :(得分:0)
您无法在a
上调用方法,因为a
不是对象,它是变量,变量不是Ruby中的对象。您在4
上调用方法,但4
不是您要修改的内容,a
是。这是不可能的。
注意:当然可以定义一个名为=
或+=
的方法并调用它,但当然这些方法只存在于对象上,而不是变量。
class Fixnum
define_method(:'+=') do |n| self + n end
end
a = 4
a.send(:'+=', 1)
# => 5
a
# => 4
答案 4 :(得分:0)
这可能会有点遗漏标记,但是我尝试这样做,其中a
实际上是在对象上动态调用的方法。例如,对于added_count
,使用updated_count
和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)
现在,如果您只有这两个不同的计数器,这似乎很愚蠢,但是在某些情况下,我们有六个或更多的计数器,并且attr的递增条件不同,因此可以方便使用。