Ruby 语法上的甜言蜜语迫使我使用难看的语句 def foo(bar) “返回值” 结束 foo'bar'#=>“返回值” def foo=(巴) “返回值” 结束 foo='bar'#=>“bar” 发送:foo=,'bar'#=>“返回值”
我希望Ruby 语法上的甜言蜜语迫使我使用难看的语句 def foo(bar) “返回值” 结束 foo'bar'#=>“返回值” def foo=(巴) “返回值” 结束 foo='bar'#=>“bar” 发送:foo=,'bar'#=>“返回值”,ruby,Ruby,我希望foo='bar'返回“返回值”,但不要为此使用send。我该怎么做 更新 我需要在我的宝石中有一个理想的行为。以下是一个例子: car=car.new car.gear#=>:第一 car.next#u gear#=>:秒 car.gear#=>:秒 car.gear=:第四个#=>错误 car.gear#=>:秒 car.gear=:第三#=>:第三 car.gear#=>:第三 您需要执行以下操作: self.foo = 'bar' 我认为它失败的原因是局部变量名在定义时优先于方
foo='bar'
返回“返回值”
,但不要为此使用send
。我该怎么做
更新
我需要在我的宝石中有一个理想的行为。以下是一个例子:
car=car.new
car.gear#=>:第一
car.next#u gear#=>:秒
car.gear#=>:秒
car.gear=:第四个#=>错误
car.gear#=>:秒
car.gear=:第三#=>:第三
car.gear#=>:第三
您需要执行以下操作:
self.foo = 'bar'
我认为它失败的原因是局部变量名在定义时优先于方法名
因此,您需要使用
send
,以便self
知道它正在寻找一个方法而不是一个变量。Assignments始终返回赋值的右侧
有关详细信息,请查看:
以等号结尾的方法表示赋值方法。
对于赋值方法,返回值被忽略,参数为
他回来了
话虽如此,foo=bar
也将赋值给局部变量foo
,而不是使用foo=
方法。同样,这在以下章节中定义:
当使用方法分配时,您必须始终具有接收器。如果你
没有接收器Ruby假定您正在分配给本地
变数
您可以通过运行
local_variables #=> []
def foo=(bar);end
foo = 42
local_variables #=> [:foo]
您可以看到局部变量foo
已创建。最好使用self.foo='bar'
为了解决您的gem的具体问题:遵循尼尔的建议,使用额外的方法,如
change\u gear
,来完成您想要做的事情。他在评论中给了你很好的评价。这是一个Ruby问题:访问器方法的返回值被忽略
此代码将更清楚地说明实际发生的情况:
#!/usr/bin/env ruby
def foo(bar)
p "called :foo w/ #{bar.inspect}"
end
def foo=(bar)
p "called :foo= with #{bar.inspect}"
end
ret = (foo :bar1) # calls foo(bar)
p "ret: #{ret}" # "ret: called :foo w/ :bar1"
ret = (foo = :bar2) # assigns a local variable foo = 'bar2'
p "ret: #{ret}" # "ret: bar2"
ret = (send :foo=, :bar3) # calls foo=(bar), returns what p returns
p "ret: #{ret}" # "ret: called :foo= with :bar3"
ret = (self.foo = :bar4) # calls foo=(bar), returns ???
p "ret: #{ret}" # "ret: bar4"
基本上,Ruby解析器(至少在2.1中)的行为就像self.foo=
在调用访问器方法一样(即使它实际上没有赋值),并且总是返回传递给它的值,而不管你发送了什么,而不是访问器的返回值
演示:
#!/usr/bin/env ruby
class << self
attr_accessor :foo
def foo=(bar)
p "called :foo= with #{bar.inspect}"
@foo = :baz
end
end
ret = (self.foo = :bar)
p "ret: #{ret} vs @foo: #{@foo.inspect}"
编辑:hat@tessi,用于:
以等号结尾的方法表示赋值方法。对于赋值方法,将忽略返回值,而返回参数
self.foo='bar'
在ruby 2上为我返回'bar'
。0@tessi:确实如此,但我认为OP遇到了Ruby bug或是被抓住了self.foo
应该调用foo=
。如果您定义一个attr\u访问器
,它确实可以做到这一点。实际上,它有更多的功能。(见我的答案。)@Denis看看我的更新。“局部变量”也是一种预期行为。是的,我认为每个人都很清楚为什么foo=42会分配局部变量,包括OP。我要强调的是,你没有解释为什么OP需要使用send foo=,…
而不是self.foo=
。(根据我的回答)这与Ruby所走的捷径有关。事实上,这不是全部答案,但也没有错。你必须有一个接收者才能让ruby调用foo=
方法。你有什么理由不能绕过赋值运算符而使用常规方法,例如def set\u foo(bar)
?我建议这样做的原因是,大多数库/作业的使用预期返回RHS的当前行为(并且改变作业应该如何工作的契约),所以只有您的代码需要其他行为。@NeilSlater,看看我的问题的更新对我来说似乎是不可取的设计。你将打破Ruby惯例,选择个人风格。用car.change\u gear:fourth
代替car.gear=:fourth
,会有什么问题?您的另一个选择是,如果有人试图设置不正确的档位,则会引发错误(可以说,这比期望用户处理assignemnt的返回值要好)
"called :foo= with :bar"
"ret: bar vs @foo: :baz"