在SO question 2068165中,一个答案提出了使用这样的东西的想法:
params[:task][:completed_at] &&= Time.parse(params[:task][:completed_at])
作为DRYer的说法
params[:task][:completed_at] = Time.parse(params[:task][:completed_at]) if params[:task][:completed_at]
其中params Hash将来自(Rails / ActionView)表单。
这是众所周知的||=
习语的必然结果,如果LHS 不 nil / false,则设置值。
这样使用&&=
实际上是一个公认的Ruby成语,我曾经错过了或者只是忘记了一个更常用的成语?它 得到了相当晚......
答案 0 :(得分:5)
它应该是。如果没有别的,params[:task]
仅在使用&&=
表单时评估一次。
澄清:
params[:task][:completed_at] = params[:task][:completed_at] && ...
在[](:task)
上params
拨打[](:completed_at)
,[]=(:completed_at)
分别params[:task]
和params[:task][:completed_at] &&= ...
。
[](:task)
在params
上调用[](:completed_at)
一次,并将其值隐藏在[]=(:completed_at)
和class X
def get
puts "get"
@hash ||= {}
end
end
irb(main):008:0> x = X.new
=> #<X:0x7f43c496b130>
irb(main):009:0> x.get
get
=> {}
irb(main):010:0> x.get[:foo] = 'foo'
get
=> "foo"
irb(main):011:0> x.get[:foo]
get
=> "foo"
irb(main):012:0> x.get[:foo] &&= 'bar'
get
=> "bar"
irb(main):013:0> x.get[:foo] = x.get[:foo] && 'bar'
get
get
=> "bar"
来电中。
描述我想要说明的实际例子(基于Marc-Andre的示例代码;非常感谢):
{{1}}
请注意,使用“展开”形式会导致“get”打印两次,但使用紧凑形式会导致它只打印一次。
答案 1 :(得分:1)
使用&&=
,如果LHS为false,则只读取一次,但不设置。这应该让它更清楚......
class Test
def initialize(value)
@v = value
end
def v=(value)
puts "set"
@v = value
end
def v
puts "get=>#{@v}"
@v
end
end
t = Test.new(true)
t.v = t.v && true
puts '----'
t.v &&= true
puts '----'
t = Test.new(false) # lets make LHS false
t.v = t.v && true
puts '----'
t = Test.new(false) # lets make LHS false
t.v &&= true
结果:
get=>true
set
----
get=>true
set
----
get=>false
set
----
get=>false