2013-08-06 2 views
2

Сегодня я видел |= в первый раз, и я пытаюсь понять, как это работает и когда это может быть полезно.Когда `` = `в Ruby полезно?

Некоторые эксперименты показывают:

var |= nil 
# => false 
var |= false 
# => false 
var |= true 
# => true 
var |= 1 
# => true 
var |= nil 
# => true 
var |= false 
# => true 
var 
# => true 

Found in Github's html-pipeline gem.

def link_to_mentioned_user(login) 
    result[:mentioned_usernames] |= [login] 
    url = File.join(base_url, login) 
    "<a href='#{url}' class='user-mention'>" + 
    "@#{login}" + 
    "</a>" 
    end 

Я предполагаю, что |= работает как охраняемом раскладка с ||=, но отбрасывает возвращаемое значение expession быть назначен булево. Это означает, что если var является ложным или неопределенным, выражение получает оценку и присваивается возвращаемое значение, присвоенное булеву. Как только вызывается var |= some_truthy_expression, var будет true, и дальнейшие звонки в var |= expression_will_not_be_called не будут оценивать выражение.

  1. Работает ли это так, где можно найти |= в Ruby docs?
  2. Когда может понадобиться |=?
+0

Я думаю, что вопрос сводится к части 1. Если это будет так, короткая резка избыточных оценок будет «удобной», верно? – Thilo

+0

Добавлена ​​неправильная ссылка раньше. Это примерно OR или сокращенное присвоение http://stackoverflow.com/q/8569039/422353 – madth3

ответ

5

для данного оператора ор, что-то вроде:

a op= b 

более или менее сокращенная для:

a = a op b 

Что | означает это, конечно, зависит от того, что вы | Факс:

  • Fo r Fixnum, это поразрядное ИЛИ.
  • Для false, true и nil это логическое ИЛИ.
  • Для Array это мужественный союз.

В вашем случае:

result[:mentioned_usernames] |= [login] 

Вы, вероятно, работать с массивами, массив на РИТ это отдать. В результате у result[:mentioned_usernames] будет добавлено login, если его там уже нет. Также есть побочный эффект: |= удалит дубликаты из result[:mentioned_usernames]; например:

>> a = [1,2,3,4,4] 
=> [1, 2, 3, 4, 4] 
>> a |= [1] 
=> [1, 2, 3, 4] 
2

foo |= bar расширяется до foo = foo | bar, который вызывает | метод объекта foo с аргументом bar. Поэтому соответствующей документацией будет документация для оператора | в любом классе foo.

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

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

Если левый операнд является массивом или задан, правый операнд также должен быть массивом или множеством, а результатом будет набор объединений двух массивов или множеств (аналогичным образом & будет установленным пересечением).

Если левый операнд является классом, который не определяет способ | (что будет в случае большинства стандартных классов, о которых я не упоминал здесь), вы получите NoMethodError.

1

Найдено ответов в Ruby |= assignment operator.

a |= b эквивалентно a = a | b, таким образом сокращенное до union arrays.

При использовании, как в примере кодовую:

results ||= [] 
results |= ['item'] # shorthand for results = results | ['item'] 
results #=> ['item'] 

# Array union excludes duplicates and preserves the order from the original array 
results |= ['item'] 
results #=> ['item'] 

Спасибо за вашу помощь. Совершенно невероятно, что можно узнать, задавая вопросы :)

Смежные вопросы