Ruby中赋值方法#bar=返回参数而非设定值,能否修改返回值?
在Ruby中让赋值表达式返回实例变量值而非右操作数
嘿,这个问题问到点子上了!先直接给结论:你没办法让foo.bar = 42这个赋值表达式本身返回@bar的值——这是Ruby语言层面的硬规则:任何赋值表达式(包括像bar=这样的属性赋值方法调用)的返回值永远是等号右边的操作数,不管你的bar=方法内部最后return了什么。
你写的示例代码完全符合这个规则:bar=方法里把@bar设成了那句星战台词,但foo.bar = 42这个表达式的结果还是42,所以puts输出42;而foo.bar能拿到正确的实例变量值,这是因为它直接读取了@bar。
不过要实现你想要的效果——执行类似赋值的操作后,直接输出@bar的值——有几种优雅的替代方式:
使用
tap方法链式调用
这是Ruby里常用的技巧,tap会把调用它的对象传给块,然后返回原对象,我们可以在块里完成赋值,接着调用bar方法拿到实例变量值:class Foo def bar=(value) @bar = "these not the droids you are looking for" end def bar @bar end end foo = Foo.new puts foo.tap { |f| f.bar = 42 }.bar # 输出"these not the droids you are looking for"自定义“带返回值的赋值方法”
如果你不想用赋值语法,可以写一个普通方法,比如set_bar,让它直接返回@bar的值:class Foo def set_bar(value) @bar = "these not the droids you are looking for" @bar # 显式返回实例变量值 end def bar @bar end end foo = Foo.new puts foo.set_bar(42) # 直接输出目标值赋值后立即取值(最直白的方式)
你也可以把赋值和取值写在一行里,用分号隔开,让puts只输出取值的结果:puts (foo.bar = 42; foo.bar) # 输出"these not the droids you are looking for"
虽然没法打破Ruby赋值表达式的返回规则,但通过上面这些方式,完全能达到你想要的“执行赋值后输出实例变量值”的效果。
内容的提问来源于stack exchange,提问作者Ulysse BN
相关产品推荐
相关产品推荐

