When Do We Use the "||=" Operator in Rails? What Is Its Significance

When do we use the ||= operator in Rails ? What is its significance?

Lets break it down:

@_current_user ||= {SOMETHING}

This is saying, set @_current_user to {SOMETHING} if it is nil, false, or undefined. Otherwise set it to @_current_user, or in other words, do nothing. An expanded form:

@_current_user || @_current_user = {SOMETHING}

Ok, now onto the right side.

session[:current_user_id] &&
User.find(session[:current_user_id])

You usually see && with boolean only values, however in Ruby you don't have to do that. The trick here is that if session[:current_user_id] is not nil, and User.find(session[:current_user_id]) is not nil, the expression will evaluate to User.find(session[:current_user_id]) otherwise nil.

So putting it all together in pseudo code:

if defined? @_current_user && @_current_user
@_current_user = @_current_user
else
if session[:current_user_id] && User.find(session[:current_user_id])
@_current_user = User.find(session[:current_user_id])
else
@_current_user = nil
end
end

What does the operator ||= stand for in Ruby?

It assigns a value if not already assigned. Like this:

a = nil
a ||= 1

a = 1
a ||= 2

In the first example, a will be set to 1. In the second one, a will still be 1.

When using IRB, what is the significance of the left side of the = operator?

The => indicates the return value of whatever code you just ran. That is, if I set

b = a.scan(/(.)(.)/) {|x,y| print y, x }

then the value of b would be cruel world. The reason it doesn't appear on a new line is that print doesn't automatically add a new line at the end of whatever it prints to the screen. If you use puts instead of print you'll see that each character appears on its own line, and => "cruel world" appears at the bottom on its own line.

What does &. (ampersand dot) mean in Ruby?

It is called the Safe Navigation Operator. Introduced in Ruby 2.3.0, it lets you call methods on objects without worrying that the object may be nil(Avoiding an undefined method for nil:NilClass error), similar to the try method in Rails.

So you can write

@person&.spouse&.name

instead of

@person.spouse.name if @person && @person.spouse

From the Docs:

my_object.my_method

This sends the my_method message to my_object. Any
object can be a receiver but depending on the method's visibility
sending a message may raise a NoMethodError.

You may use &. to designate a receiver, then my_method is not invoked
and the result is nil when the receiver is nil. In that case, the
arguments of my_method are not evaluated.

Why are exclamation marks used in Ruby methods?

In general, methods that end in ! indicate that the method will modify the object it's called on. Ruby calls these as "dangerous methods" because they change state that someone else might have a reference to. Here's a simple example for strings:

foo = "A STRING"  # a string called foo
foo.downcase! # modifies foo itself
puts foo # prints modified foo

This will output:

a string

In the standard libraries, there are a lot of places you'll see pairs of similarly named methods, one with the ! and one without. The ones without are called "safe methods", and they return a copy of the original with changes applied to the copy, with the callee unchanged. Here's the same example without the !:

foo = "A STRING"    # a string called foo
bar = foo.downcase # doesn't modify foo; returns a modified string
puts foo # prints unchanged foo
puts bar # prints newly created bar

This outputs:

A STRING
a string

Keep in mind this is just a convention, but a lot of Ruby classes follow it. It also helps you keep track of what's getting modified in your code.

equality and null check (Ruby-on-Rails and c#)

Based on what I have read here, the x ||= y operator works like:

This is saying, set x to y if x is nil, false, or undefined. Otherwise set it to x.

(modified, generalized, formatting added)

The null-coalescing operator ?? on the other hand is defined like:

The ?? operator is called the null-coalescing operator. It returns the left-hand operand if the operand is not null; otherwise it returns the right hand operand.

(formatting added)

Based on that there are two important differences:

  1. The ?? does not assign, it is like a ternary operator. The outcome can be assigned, but other things can be done with it: assign it to another variable for instance, or call a method on it; and
  2. The ?? only checks for null (and for instance not for false), whereas ||= works with nil, false and undefined.

But I agree they have some "similar purpose" although || in Ruby is probably more similar with ??, but it still violates (2).

Also mind that the left part of the null-coalescing operator does not have to be a variable: on could write:

Foo() ?? 0

So here we call a Foo method.

what is the functionality of &: operator in ruby?

There isn't a &: operator in Ruby. What you are seeing is the & operator applied to a :symbol.

In a method argument list, the & operator takes its operand, converts it to a Proc object if it isn't already (by calling to_proc on it) and passes it to the method as if a block had been used.

my_proc = Proc.new { puts "foo" }

my_method_call(&my_proc) # is identical to:
my_method_call { puts "foo" }

So the question now becomes "What does Symbol#to_proc do?", and that's easy to see in the Rails documentation:

Turns the symbol into a simple proc, which is especially useful for enumerations. Examples:

# The same as people.collect { |p| p.name }
people.collect(&:name)

# The same as people.select { |p| p.manager? }.collect { |p| p.salary }
people.select(&:manager?).collect(&:salary)

What is Ruby's double-colon `::`?

:: is basically a namespace resolution operator. It allows you to access items in modules, or class-level items in classes. For example, say you had this setup:

module SomeModule
module InnerModule
class MyClass
CONSTANT = 4
end
end
end

You could access CONSTANT from outside the module as SomeModule::InnerModule::MyClass::CONSTANT.

It doesn't affect instance methods defined on a class, since you access those with a different syntax (the dot .).

Relevant note: If you want to go back to the top-level namespace, do this: ::SomeModule – Benjamin Oakes

Significance of colon : in Ruby

A colon denotes a "symbol". A symbol is like a string, but it is immutable (you can't change its contents). Behind the scenes, it also takes up less memory, since a symbol only needs to exist once in memory (i.e., two strings called "length" will exist twice in memory, but two symbols called :length will point to the same object).



Related Topics



Leave a reply



Submit