Что означает || = (или-равно) в Ruby? - PullRequest
310 голосов
/ 15 июня 2009

Что означает следующий код в Ruby?

||=

Имеет ли оно какое-либо значение или причину для синтаксиса?

Ответы [ 22 ]

2 голосов
/ 13 мая 2013
a ||= b

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

a || a = b

а не

a = a || b

из-за ситуации, когда вы определяете хеш со значением по умолчанию (хеш вернет значение по умолчанию для любых неопределенных ключей)

a = Hash.new(true) #Which is: {}

если вы используете:

a[10] ||= 10 #same as a[10] || a[10] = 10

а еще:

{}

но когда вы пишете это так:

a[10] = a[10] || 10

становится:

{10 => true}

потому что вы присвоили себе значение в ключе 10, который по умолчанию имеет значение true, поэтому теперь для ключа 10 определен хэш, а не выполнять присвоение в первую очередь.

2 голосов
/ 12 октября 2015

Пожалуйста, помните, что ||= не является атомарной операцией и поэтому не является поточно-ориентированным. Как правило, не используйте его для методов класса.

2 голосов
/ 01 июля 2014

Это обозначение назначения по умолчанию

например: x || = 1
это проверит, чтобы видеть, является ли x нулем или нет. Если x действительно равен nil, ему будет присвоено это новое значение (1 в нашем примере)

более явно:
если х == ноль
х = 1
конец

2 голосов
/ 29 сентября 2013

Это как ленивый экземпляр. Если переменная уже определена, она примет это значение вместо того, чтобы создавать его заново.

1 голос
/ 25 августа 2016

Как общее заблуждение, a ||= b не эквивалентно a = a || b, но ведет себя как a || a = b.

Но тут возникает сложный случай. Если a не определено, a || a = 42 повышает NameError, а a ||= 42 возвращает 42. Таким образом, они не являются эквивалентными выражениями.

0 голосов
/ 31 августа 2018

|| = является оператором условного присваивания

  x ||= y

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

  x = x || y

или альтернативно

if defined?(x) and x
    x = x
else 
    x = y
end
0 голосов
/ 28 августа 2018

a ||= b - это то же самое, что сказать a = b if a.nil? или a = b unless a

Но все ли 3 варианта показывают одинаковую производительность? С Ruby 2.5.1 это

1000000.times do
  a ||= 1
  a ||= 1
  a ||= 1
  a ||= 1
  a ||= 1
  a ||= 1
  a ||= 1
  a ||= 1
  a ||= 1
  a ||= 1
end

занимает на моем ПК 0,099 секунды, а

1000000.times do
  a = 1 unless a
  a = 1 unless a
  a = 1 unless a
  a = 1 unless a
  a = 1 unless a
  a = 1 unless a
  a = 1 unless a
  a = 1 unless a
  a = 1 unless a
  a = 1 unless a
end

занимает 0,062 секунды. Это почти на 40% быстрее.

и тогда у нас также есть:

1000000.times do
  a = 1 if a.nil?
  a = 1 if a.nil?
  a = 1 if a.nil?
  a = 1 if a.nil?
  a = 1 if a.nil?
  a = 1 if a.nil?
  a = 1 if a.nil?
  a = 1 if a.nil?
  a = 1 if a.nil?
  a = 1 if a.nil?
end

, что занимает 0,166 секунды.

В общем, это не окажет существенного влияния на производительность, но если вам нужен последний бит оптимизации, рассмотрите этот результат. Кстати: a = 1 unless a новичку легче читать, это само за себя.

Примечание 1: причиной многократного повторения строки назначения является уменьшение накладных расходов цикла на измеренное время.

Примечание 2: Результаты аналогичны, если я делаю a=nil ноль перед каждым назначением.

0 голосов
/ 03 апреля 2017

||= называется оператором условного присваивания.

В основном это работает как =, но за исключением того, что если переменной уже присвоена , она ничего не будет делать.

Первый пример:

x ||= 10

Второй пример:

x = 20
x ||= 10

В первом примере x теперь равен 10. Однако во втором примере x уже определен как 20. Таким образом, условный оператор не имеет эффекта. x по-прежнему 20 после запуска x ||= 10.

0 голосов
/ 21 октября 2016
b = 5
a ||= b

Это означает:

a = a || b

что будет

a = nil || 5

так наконец

a = 5

Теперь, если вы позвоните еще раз:

a ||= b
a = a || b
a = 5 || 5
a = 5

b = 6

Теперь, если вы позвоните еще раз:

a ||= b
a = a || b
a = 5 || 6
a = 5 

Если вы наблюдаете, значение b не будет присвоено a. a будет по-прежнему иметь 5.

Это шаблон памятки, который используется в Ruby для ускорения доступа.

def users
  @users ||= User.all
end

Это в основном означает:

@users = @users || User.all

Таким образом, вы вызовете базу данных в первый раз, когда вызовете этот метод.

Будущие вызовы этого метода просто вернут значение @users переменной экземпляра.

0 голосов
/ 29 апреля 2019

a || = b

Указывает, присутствует ли какое-либо значение в «a», и вы не хотите изменять его, продолжая использовать это значение, иначе, если «a» не имеет никакого значения, используйте значение «b».

Простые слова, если слева, если не ноль, указывают на существующее значение, в противном случае указывают на значение справа.

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