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
How to Start the Ruby Debugger on Exception
Navigate to Ruby Function Definition in VS Code
How to Validate the Presence of a Belongs to Association with Rails
Installing Ruby 2.3 on Wsl (Windows Subsystem for Linux)
What's the Difference Between Arrays and Hashes
Installing a Gem from Github with Bundler
Rails 3: Call Functions Inside Controllers
How to Add Confirm Message with Link_To Ruby on Rails
Appending to Rake Db:Seed in Rails and Running It Without Duplicating Data
Using Named Captures with Regex Match in Ruby's Case...When
Simple_Form's Collection_Radio_Button and Custom Label Class
Converting Nested Hash Keys from Camelcase to Snake_Case in Ruby
Nameerror: Uninitialized Constant Faker
Make: /Usr/Bin/Mkdir: Command Not Found During 'Gem Install Nokogiri' in Ubuntu 20.04
Convert String to Class Name Without Using Eval in Ruby
How to Convert a Net::Http Response to a Certain Encoding in Ruby 1.9.1
Convert Array to Hash While Preserving Array Index Values in Ruby