Работает ли @x || = как @x, если @ x.present? - PullRequest
2 голосов
/ 28 мая 2019

Это:

def x?
  return @x if @x.present?

  @x = #boolean calculation
end

Эквивалентно этому для логических значений @x?

def x?
  @x ||= #boolean calculation
end

Ответы [ 3 ]

6 голосов
/ 28 мая 2019

Не следует использовать ни одну из опций для запоминания значений boolean, так как оба будут пересчитаны, если @x равно false.

present? - это особый вид проверки рельсов, равный !blank? и false.blank? #=> true, но даже если это не логическая проверка present? и || не эквивалентны.Для объектов, которые реализуют empty?, пробел относится к этому, поэтому что-то, что empty? также равно blank? и, следовательно, не present?.

"".present? #=> false
"" || true #=> "" 
[].present? #=> false
[] || true #=> [] 
false.present? #=> false
false || true #=> true

@x ||= some_logic равно @x = @x || some_logic, где, очевидно,если @x ложно some_logic сработает.

Если вы просто хотите увидеть, было ли @x уже определено как значение (например, не nil), тогда вы можете заменить его на

def x? 
  return @x unless @x.nil? 
  @x = some_logic
end
0 голосов
/ 28 мая 2019

TL; DR: Нет

Просто добавьте больше примеров к ответам, уже приведенным выше:

def x1?(new_value)
  return @x if @x.present?

  @x = new_value
end

def x2?(new_value)
  @x ||= new_value
end

скажем @x было числом:

@x = 123
x1?('new value')
@x
# => 123

@x = 123
x2?('new value')
@x
# => 123

# 123 == 123, so this works for `Number`

но, скажем, @x был пустым массивом:

@x = []
x1?('new value')
@x
# => 'new value'

@x = []
x2?('new value')
@x
# => []

# 'new value' != [], so it doesn't work for empty Array.

^ и есть все другие "типы", которые не работают так же хорошо, не просто пустой массив, некоторыездесь уже отвечали другие.

0 голосов
/ 28 мая 2019

Это зависит.

@x ||= value

эквивалентно

@x = @x || value

, которое присваивает value @x, только если @x ложно.В Ruby только false и nil являются ложными.

Далее, #present? - это концепция от Rails (см. doc ).

Обратите внимание, чтов зависимости от значения, которое вы планируете хранить в @x, оно может быть эквивалентным.#present? - это просто отрицание #blank? (также концепция Rails).#blank? определяется для Object следующим образом:

def blank?
  respond_to?(:empty?) ? !!empty? : !self
end

Таким образом, поведение двух опубликованных вами фрагментов гарантированно будет эквивалентным, когда @x содержит значение, которое не определяет его собственноеМетоды #present?, #blank? или #empty?.

Теперь FalseClass и NilClass оба определяют #blank?:

def blank?
  true
end

TrueClass также определяет #blank?:

def blank?
  false
end

Но это всего лишь оптимизация, поскольку реализация по умолчанию из Object приведет к тем же значениям.

Следовательно, false и nil вернут false для #present?, а true вернут true для #present?.

Из этого мы заключаем, чтов конкретном случае хранения логических значений в @x поведение двух фрагментов эквивалентно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...