Действительно ли это - разумное использование для && = в Ruby?

В ТАК вопросе 2 068 165 один ответов повысили идею использовать что-то вроде этого:

params[:task][:completed_at] &&= Time.parse(params[:task][:completed_at])

как СУШИЛКА способ сказать

params[:task][:completed_at] = Time.parse(params[:task][:completed_at]) if params[:task][:completed_at]

куда Хеш параметрических усилителей прибыл бы из (Rails/ActionView) форма.

Это - своего рода заключение к известному ||= идиома, устанавливая значение, если LHS не является нолем/ложью.

Использует &&= как это на самом деле распознанная идиома Ruby, которую я так или иначе пропустил или я только что забыл более наиболее часто используемую идиому? Становится довольно поздно...

7
задан Community 23 May 2017 в 11:47
поделиться

2 ответа

Это должно быть. Если ничего другого, Params [: задание] оценивается только один раз при использовании формы && = .

Чтобы уточнить:

params[:task][:completed_at] = params[:task][:completed_at] && ...

вызовы [] (: задание) на парам дважды, [] (: CONECTED_AT) и [] = (: завершено_at) Один раз на params [: задание] .

params[:task][:completed_at] &&= ...

Вызывы [] (: задание) на на один раз один раз, и его значение скрывается как для [] (: CONECTED_AT) , и [] = (: Завершено_at) звонки.


Фактический пример, описывающий то, что я пытаюсь проиллюстрировать (на основе примерного кода Marc-Andre; большое спасибо):

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"

Обратите внимание, что использование формы «расширенного» вызывает «получить», чтобы быть напечатаны дважды, но используя Компактная форма заставляет его быть напечатаны только один раз.

5
ответ дан 7 December 2019 в 10:02
поделиться

Использование && = , в случае LHS является ложным, он только один раз прочитан, но не устанавливается. Это должно сделать это более понятнее ...

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
1
ответ дан 7 December 2019 в 10:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: