anyone care to explain what this syntax means in Ruby?
class Animal
def name_category
@animals ||={}
end
end
Also, is there a way for setting up object variable without using attr_accessor, attr_reader, attr_writer or def initialize?
||=
is Ruby's conditional assignment operator. a ||= b
can usually be taken as short for
a || (a = b)
That is, a
is assigned b
if a
is nil
or false
(i.e., a = b
conditional on the falsiness of a
).
The operator exploits a property of the way ||
is evaluated. Namely, that the right-hand operand of ||
is not evaluated unless the left-hand one is truthy (i.e., not false
or nil
). This is known as short-circuiting.
In your case, unless @animals
already possesses a non-falsy value, it will be bound to an empty hash {}
.
It's important to note that despite the superficial similarity of ||=
to operators like +=
and -=
, a ||= b
is not equivalent to a = a || b
.
For a counterexample, take a = Hash.new(true)
. Then:
a[:key] ||= :value
#=> true
a
#=> {}
Compare with
a[:key] = a[:key] || :value
#=> true
a
#=> {:key=>true}
However, strictly speaking a ||= b
is also not equivalent to a || a = b
. If a
is undefined, then
>> a || a = false
#=> NameError: undefined local variable or method `a' for main:Object
but
>> a ||= false
#=> false
and
>> a = a || false
#=> false
Something to keep in mind.
So it’s more accurate, if less syntactically elegant, to say that a ||= b
is equivalent to
(defined?(a) && a) ? a : a = b
Here's a good post on Ruby Inside elaborating on this point further.
It's equivalent to (really long hand unpretty form):
if @animal == nil # (falsey really, but nil is what we're looking for here)
@animal = {}
end
return @animal
Basically: return @animal, unless it's not initialized in which case initialized it to {} before return it.
You could also write it as:
@animal = {} unless @animal
return @animal
Or
@animal ||= {}
return @animal
But then @animal ||= {} evaluates to @animal anyway, and you can skip the return
@
declares it an instance variable, and it's initialized tonil
unless assigned to something else. – Jake Romerattr_
methods are just a shorthand way of declaring setters and getters for your instance variables, so if you just haveattr_accessor :name
without assigning anything to@name
anywhere inside of your class definition,#name
will just returnnil
unless you assign it something with#name=
. – Jake Romer