Подтвердить что ты не робот

Символы с двойной трубкой в ​​задании переменной Ruby?

Возможный дубликат:
Что означает || = в Ruby?

Простите меня, если это новый вопрос, но я читаю книгу о рельсах, где автор использовал это выражение в вспомогательном методе:

@current_user ||= User.find_by_id(session[:user_id])

Является ли это использование двойных каналов еще логическим оператором OR?

Если да, то как это работает?

4b9b3361

Ответ 1

Это условное задание. Из здесь:

 x = find_something() #=>nil
 x ||= "default"      #=>"default" : value of x will be replaced with "default", but only if x is nil or false
 x ||= "other"        #=>"default" : value of x is not replaced if it already is other than nil or false

Ответ 2

Код foo ||= bar почти эквивалентен foo = foo || bar. В Ruby (как на многих языках, таких как JavaScript или Io) логические операторы являются "защитными" операторами. Вместо того, чтобы всегда возвращать true или false, они вычисляют значение первого операнда, который оценивает "правдивое" значение.

Например, этот код foo = 1 || delete_all_files_from_my_computer() ничего не удалит: foo будет установлен в 1, а второй операнд даже не будет оценен.

В Ruby единственными значениями "неправды" являются nil и false. Таким образом, код foo ||= bar будет оценивать только bar и устанавливать foo на результат, если foo равен nil или false.

В качестве переменных экземпляра по умолчанию используется nil, если он не установлен, код типа @foo ||= bar является обычной идикой Ruby для установки переменной экземпляра, если она еще не была установлена.

Ответ 3

Вы можете думать об этом как о сокращении:

@current_user = @current_user || User.find_by_id(session[:user_id])

@current_user оценивается первым, если оно не равно нулю, то замыкается ИЛИ, возвращая значение @current_user и не вызывая User.find_by_id.

(Это работает только потому, что Ruby рассматривает null как false и ненулевое как true в логическом контексте. Он не работает для языков, таких как Java, которые не рассматривают non-booleans как истинные.)