Difference Between || and ||=

Difference between || and ||=?

||= will set the left-hand value to the right hand value only if the left-hand value is falsey.

In this case, both 6 and 4 are truthy, so a = 6 || 4 will set a to the first truthy value, which is 6.

a ||= 6 will set a to 6 only if a is falsey. That is, if it's nil or false.

a = nil
a ||= 6
a ||= 4
a # => 6

Difference between || and ?? operators

The main difference is that nullish coalescing(??) operator will only give the result as the right operand only if the left operand is either null or undefined.

Whereas the OR(||) operator will give the result as right operand for all the falsy values of the left operand.

Below are some examples

  • Snippet 1: With 0 as input

const a = 0;
// a || 10 --> Will result in 10, as || operator considers 0 as falsy value and resulting the right side operand
console.log(`a || 10 = ${a || 10}`);
// a ?? 10 --> Will result in 0, as ?? operator considers 0 as truthy value and resulting the left side operand
console.log(`a ?? 10 = ${a ?? 10}`);

Why do we usually use || over |? What is the difference?

If you use the || and && forms, rather than the | and & forms of these operators, Java will not bother to evaluate the right-hand operand alone.

It's a matter of if you want to short-circuit the evaluation or not -- most of the time you want to.

A good way to illustrate the benefits of short-circuiting would be to consider the following example.

Boolean b = true;
if(b || foo.timeConsumingCall())
{
//we entered without calling timeConsumingCall()
}

Another benefit, as Jeremy and Peter mentioned, for short-circuiting is the null reference check:

if(string != null && string.isEmpty())
{
//we check for string being null before calling isEmpty()
}

more info

difference between || and ||= in this situation

You're facing this issue becuase you're not check value returned from store_user method, but user[:user_uid] value (exactly as @Neil Slater said). So, if you use ||, user[:user_uid] remains nil. But if you use ||=, user[:user_uid] is set to value returned by next_uid method.

What does ||= (or-equals) mean in Ruby?

This question has been discussed so often on the Ruby mailing-lists and Ruby blogs that there are now even threads on the Ruby mailing-list whose only purpose is to collect links to all the other threads on the Ruby mailing-list that discuss this issue.

Here's one: The definitive list of ||= (OR Equal) threads and pages

If you really want to know what is going on, take a look at Section 11.4.2.3 "Abbreviated assignments" of the Ruby Language Draft Specification.

As a first approximation,

a ||= b

is equivalent to

a || a = b

and not equivalent to

a = a || b

However, that is only a first approximation, especially if a is undefined. The semantics also differ depending on whether it is a simple variable assignment, a method assignment or an indexing assignment:

a    ||= b
a.c ||= b
a[c] ||= b

are all treated differently.

What is the difference between || and or in Perl?

From Perl documentation:

OR

List operators

On the right side of a list operator, it has very low precedence, such that it controls all comma-separated expressions found there. The only operators with lower precedence are the logical operators "and", "or", and "not", which may be used to evaluate calls to list operators without the need for extra parentheses.

Logical or, defined or, and exclusive or.

Binary "or" returns the logical disjunction of the two surrounding expressions. It's equivalent to ||, except for the very low precedence. This makes it useful for control flow

print FH $data or die "Can't write to FH: $!";

This means that it short-circuits: i.e., the right expression is evaluated only if the left expression is false. Due to its precedence, you should probably avoid using this for assignment, only for control flow.

$a = $b or $c; # Bug: this is wrong

($a = $b) or $c; # Really means this

$a = $b || $c; # Better written this way

However, when it's a list-context assignment and you're trying to use "||" for control flow, you probably need "or" so that the assignment takes higher precedence.

@info = stat($file) || die; # Oops, scalar sense of stat!

@info = stat($file) or die; # Better, now @info gets its due

Then again, you could always use parentheses.

||

If any list operator (print(), etc.) or any unary operator (chdir(), etc.) is followed by a left parenthesis as the next token, the operator and arguments within parentheses are taken to be of highest precedence, just like a normal function call.



For example, because named unary operators have higher precedence than ||:

chdir $foo || die; # (chdir $foo) || die

chdir($foo) || die; # (chdir $foo) || die

chdir ($foo) || die; # (chdir $foo) || die

chdir +($foo) || die; # (chdir $foo) || die

Whats the dfference between ||= and |= with booleans

That's not quite right. In general the X= operator behaves like A = A X B where X is one of the supported operators. Notably it's always on the right side of the =.

That being said, | and || are two very different operators. The | version is typically understood to do binary math, as in:

2 | 1
# => 3

Where that's the result of 0b10 and 0b01 being combined with a binary OR.

It also does array unions:

[ 1, 2 ] | [ 2, 3 ]
# => [ 1, 2, 3 ]

Whereas || a higher level logical test on the truthiness of values. In Ruby only nil and false are considered non-truthful, all other values are considered truthful, so:

0 || 1
# => 0
false || true
# => true
nil || "yes"
# => "yes"

The same principle applies to & and &&.

Interestingly | and & are method calls and their actual functionality depends on what's on the left side of the operator, while || and && are syntactic elements you cannot change and always work the same way.

So where do |= and ||= come into play? There's a few cases where you'll see them.

Setting bitflags:

flags |= 0b0010

Applying defaults:

max ||= MAX_DEFAULT

When should I use ?? (nullish coalescing) vs || (logical OR)?

The OR operator || uses the right value if left is falsy, while the nullish coalescing operator ?? uses the right value if left is null or undefined.

These operators are often used to provide a default value if the first one is missing.

But the OR operator || can be problematic if your left value might contain "" or 0 or false (because these are falsy values):

console.log(12 || "not found") // 12
console.log(0 || "not found") // "not found"

console.log("jane" || "not found") // "jane"
console.log("" || "not found") // "not found"

console.log(true || "not found") // true
console.log(false || "not found") // "not found"

console.log(undefined || "not found") // "not found"
console.log(null || "not found") // "not found"

In many cases, you might only want the right value if left is null or undefined. That's what the nullish coalescing operator ?? is for:

console.log(12 ?? "not found") // 12
console.log(0 ?? "not found") // 0

console.log("jane" ?? "not found") // "jane"
console.log("" ?? "not found") // ""

console.log(true ?? "not found") // true
console.log(false ?? "not found") // false

console.log(undefined ?? "not found") // "not found"
console.log(null ?? "not found") // "not found"

While the ?? operator isn't available in current LTS versions of Node (v10 and v12), you can use it with some versions of TypeScript or Node:

The ?? operator was added to TypeScript 3.7 back in November 2019.

And more recently, the ?? operator was included in ES2020, which is supported by Node 14 (released in April 2020).

When the nullish coalescing operator ?? is supported, I typically use it instead of the OR operator || (unless there's a good reason not to).

Difference between a = a || b and a ||= b

Quoting the resource here:

In a = a || b, a is set to something by the statement on every run,
whereas with a || a = b, a is only set if a is logically false (i.e.
if it's nil or false) because || is 'short circuiting'. That is, if
the left hand side of the || comparison is true, there's no need to
check the right hand side.

This basically means they'll behave similarly to you, the dev, but internally the implementations differ as explained above.

EDIT:
As pointed out in the comments, the above explanation considers a || a = b instead of a ||= b. A very good point, and reading the same link further clarifies this:

If a is not defined, a || a = 42 raises NameError, while a ||= 42
returns 42. So, they don't seem to be equivalent expressions.

So, again, they're not the same statement, because Ruby allocates a variable the moment it sees an assignment at parse-time (which is the case for a ||= 42).

One final quote so you don't think I'm making this up, :)

Ruby sees the assignment at the parsing stage and creates the variable
in a way that it wouldn't with a || a = 42, even though it ends up
behaving like the latter once actual execution occurs.



Related Topics



Leave a reply



Submit