Clarification on the Ruby << Operator

Clarification on the Ruby Operator

Ruby is an object-oriented language. The fundamental principle of object orientation is that objects send messages to other objects, and the receiver of the message can respond to the message in whatever way it sees fit. So,

a << b

means whatever a decides it should mean. It's impossible to say what << means without knowing what a is.

As a general convention, << in Ruby means "append", i.e. it appends its argument to its receiver and then returns the receiver. So, for Array it appends the argument to the array, for String it performs string concatenation, for Set it adds the argument to the set, for IO it writes to the file descriptor, and so on.

As a special case, for Fixnum and Bignum, it performs a bitwise left-shift of the twos-complement representation of the Integer. This is mainly because that's what it does in C, and Ruby is influenced by C.

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

In Ruby, how does the shovel operator ( ) work on two integers?

The operation is called “bitwise left shift” and is easily googlable by this term.

In short, it takes the binary representation of the LHO and shifts it to the left by count, specified as RHO.

Consider you have 5 << 2. 5 is represented by (64bits):

0000 0000 0000 0101

Left shift by 2 would be:

00 0000 0000 0101 00 # = 0000 0000 0001 0100

or, in turn, 20. Let’s check:

5 << 2
#⇒ 20

Due to the nature of binary numeral base system, left shift is equivalent to multiplying by the respective power of 2. That said,

m << n ≡ m × 2ⁿ

5 << 4 #⇒ 5 × 2⁴ ≡ 80
#⇒ 80

Need clarification on Ruby logical operators

As opposed to other languages like C, in Ruby all values except for nil and false are considered “truthy”. This means, that all these values behave like true in the context of a boolean expression.

Ruby's boolean operators will not return true or false. Instead, they return the first operand that causes the evaluation of the condition to be complete (also known as short-circuit evaluation). For boolean and that means, it will either return the first “falsy” operand or the last one:

false && 1    # => false     (falsy)
nil && 1 # => nil (falsy)
false && nil # => false (falsy)
1 && 2 # => 2 (truthy)

For boolean or that means, it will either return the first “truthy” operand or the last one:

false || 1    # => 1         (truthy)
nil || 1 # => 1 (truthy)
false || nil # => nil (falsy)
1 || 2 # => 1 (truthy)

This allows for some interesting constructs. It is a very common pattern to use || to set default values, for example:

def hello(name)
name = name || 'generic humanoid'
puts "Hello, #{name}!"
end

hello(nil) # Hello, generic humanoid!
hello('Bob') # Hello, Bob!

Another similar way to acheive the same thing is

name || (name = 'generic humanoid')

With the added benefit that if name is truthy, no assignment is performed at all. There is even a shortcut for this assignment of default values:

name ||= 'generic humanoid'

If you paid careful attention you will have noticed that this may cause some trouble, if one valid value is false:

destroy_humans = nil
destroy_humans ||= true
destroy_humans
#=> true

destroy_humans = false
destroy_humans ||= true
destroy_humans
#=> true, OMG run!

This is rarely the desired effect. So if you know that the values can only be a String or nil, using || and ||= is fine. If the variable can be false, you have to be more verbose:

destroy_humans = nil
destroy_humans = true if destroy_humans.nil?
destroy_humans
#=> true

destroy_humans = false
destroy_humans = true if destroy_humans.nil?
destroy_humans
#=> false, extinction of humanity digressed!

That was close! But wait, there is another caveat – specifically with the usage of and and or. These should never be used for boolean expressions, because they have very low operator precedence. That means they will be evaluated last. Consider the following examples:

is_human = true
is_zombie = false
destroy_human = is_human && is_zombie
destroy_human
#=> false

is_human = true
is_zombie = false
destroy_human = is_human and is_zombie
destroy_human
#=> true, Waaaah but I'm not a zombie!

Let me add some parentheses to clarify what's happening here:

destroy_human = is_human && is_zombie
# equivalent to
destroy_human = (is_human && is_zombie)

destroy_human = is_human and is_zombie
# equivalent to
(destroy_human = is_human) and is_zombie

So and and or are really just useful as “control-flow operators”, for example:

join_roboparty or fail 'forever alone :('
# this will raise a RuntimeError when join_roboparty returns a falsy value

join_roboparty and puts 'robotz party hard :)'
# this will only output the message if join_roboparty returns a truthy value

I hope that clarifies everything you need to know about these operators. It takes a bit of getting used to, because it differs from the way other languages handle it. But once you know how to use the different options, you've got some powerful tools at hand.

What is the = operator on Ruby Classes?

See http://ruby-doc.org/core/classes/Module.html#M001669 for documentation on all the comparison operators exposed by Modules (and therefore Classes).

In this specific case:
"Returns true if mod is a subclass of other or is the same as other. Returns nil if there‘s no relationship between the two. (Think of the relationship in terms of the class definition: "class A < B" implies "A < B")."

what is the difference between += and =+ in ruby?

There's no such token as =+; it's actually two tokens: assignment followed by the unary + operator; the latter is essentially a no-op, so @@num_things =+ 1 is equivalent to @@num_things = 1.

Since there is a += token, the language parser will parse it as a single token.

(In the early formulations of BCPL which was the precursor to C, the modern -= operator was written as =-.)

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 do you call the - operator in Ruby?

In Ruby Programming Language ("Methods, Procs, Lambdas, and Closures"), a lambda defined using -> is called lambda literal.

succ = ->(x){ x+1 }
succ.call(2)

The code is equivalent to the following one.

succ = lambda { |x| x + 1 }
succ.call(2)

Informally, I have heard it being called stabby lambda or stabby literal.

Ruby |= assignment operator

Bitwise OR assignment.

x |= y

is shorthand for:

x = x | y

(just like x += y is shorthand for x = x + y).



Related Topics



Leave a reply



Submit