문제

I have the impression I can use

bool &= true
# and
bool &&= true
# indifferently

Is there any difference between two? Is one solution unrecommended?

Actually

bool = true & false # false

So what's the difference between & and && in general? (I guess the same applies for ||)

도움이 되었습니까?

해결책

Try the following:

x = 5
x |= 2
=> 7

|= and &= are equivalent to the bitwise x = x | 2 and x = x & 2

vs

x = 5
x ||= 2
=> 5

In the second statement, x ||= 2, it means x = 2 if x is nil, otherwise it's x. ( x = (x || 2) ; the expression x || 2 returns x if x is anything but nil otherwise it returns 2.

x ||= 'foo' is actually very common in Ruby (set x to foo is x is not already set)

x = (x & 3) (which is equivalent to x &= 3), returns 3 (the second operand) unless x is 0, it returns 0) )

The same logic applies for & but it was easier to find an example on the top of my mind for |

=)

다른 팁

The main difference between the keywords is that the first | is a method, and can be redefined for a class, and the second || is not, and can be never defined as a method, and just used for language syntax, as you can see in example below:

Array.new.respond_to?( :| )
# => true 
Array.new.respond_to?( :|| )
SyntaxError: (irb):35: syntax error, unexpected tOP_ASGN, expecting tSTRING_CONTENT or tSTRING_DBEG or tSTRING_DVAR or tSTRING_END

So, when you have applied the #| method it is able to return a value that differs from true, or false. Although for ruby's TrueClass, and FalseClass those values are true or false, but other descendants could redefine the return value, however, for Array and Set classes it implements functions similar to boolean bitwise operation. So can be sure that the true or false class's methods return also true or false. Otherwise, the keyword || is real language boolean operator, however it operates with values true, and not-true, you can see it on example:

'value1' || 'value2'
# => "value1" 
true || false
# => true
'value1' || false
# => "value1" 
false || 'value2'
# => "value2" 

The return valus is always subordinated to logical expression, but the values of it are, as I denoted above, true, and not-true. Therefore you see in example return values not only of true/false pair, but of the real variable values too, and you can use it as if conditional operators as follows:

'value1' || 'value2'

and

if 'value1'
   'value1'
else
   'value2'
end

will return the same value.

According the or-equal assignment we see the following:

A |= false
# NameError: uninitialized constant A
a |= false
# false
A ||= false
# => false 

In first case we are able to split |= operation into the two: call to #| method, and to assign the result to the variable. In the second case the ruby interpreter sees the whole operator ||=, verifies weither it is nil or undefined, and if yes assign to the variable or to the const the expression result.

The pair &, && has the same explanation.

When you are only using the & operator on boolean values, then there is no difference to &&, but if you want to use it with functions that return a boolean value then there is a difference. Have a look at this code:

def side_effect(message="hello")
    puts message
    true
end

#writes "hello" 2 times to the console and then returns false
false & side_effect & side_effect

# just returns false without writing "hello" to the console.
false && side_effect && side_effect
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top