这对于Ruby中的&& =是合理的用途吗?

时间:2010-01-15 00:25:42

标签: ruby operators

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成语,我曾经错过了或者只是忘记了一个更常用的成语?它 得到了相当晚......

2 个答案:

答案 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