What Does a ||= Mean in Ruby Language

What does ||= mean?

Basically, a ||= b means assign b to a if a is null or undefined or false (i.e. false-ish value in ruby), it is similar to a = b unless a, except it will always evaluate to the final value of a (whereas a = b unless a would result in nil if a was true-ish).

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 does ||= mean?

It is an assignment operator which means: or assign this value to a variable.

So if you did something like x ||= ythis meansx || x = y so if x is nil or false set x to be the value of y.

What does the (unary) * operator do in this Ruby code?

The * is the splat operator.

It expands an Array into a list of arguments, in this case a list of arguments to the Hash.[] method. (To be more precise, it expands any object that responds to to_ary/to_a, or to_a in Ruby 1.9.)

To illustrate, the following two statements are equal:

method arg1, arg2, arg3
method *[arg1, arg2, arg3]

It can also be used in a different context, to catch all remaining method arguments in a method definition. In that case, it does not expand, but combine:

def method2(*args)  # args will hold Array of all arguments
end

Some more detailed information here.

In Ruby what does = mean and how does it work?

=> separates the keys from the values in a hashmap literal. It is not overloadable and not specifically connected to symbols.

A hashmap literal has the form {key1 => value1, key2 => value2, ...}, but when used as the last parameter of a function, you can leave off the curly braces. So when you see a function call like f(:a => 1, :b => 2), f is called with one argument, which is a hashmap that has the keys :a and :b and the values 1 and 2.

what does this syntax mean in Ruby? .. tasks.all?(&:complete?)

& is for passing block to method as a block (also used the other way in parameter list to make implicit block a parameter), it implicitly calls to_proc on passed object.

Symbol#to_proc for :symbol makes a proc{|param| param.symbol }

So your code is equvalent to tasks.all?{|task| task.complete? }

What does @@variable mean in Ruby?

A variable prefixed with @ is an instance variable, while one prefixed with @@ is a class variable. Check out the following example; its output is in the comments at the end of the puts lines:

class Test
@@shared = 1

def value
@@shared
end

def value=(value)
@@shared = value
end
end

class AnotherTest < Test; end

t = Test.new
puts "t.value is #{t.value}" # 1
t.value = 2
puts "t.value is #{t.value}" # 2

x = Test.new
puts "x.value is #{x.value}" # 2

a = AnotherTest.new
puts "a.value is #{a.value}" # 2
a.value = 3
puts "a.value is #{a.value}" # 3
puts "t.value is #{t.value}" # 3
puts "x.value is #{x.value}" # 3

You can see that @@shared is shared between the classes; setting the value in an instance of one changes the value for all other instances of that class and even child classes, where a variable named @shared, with one @, would not be.

[Update]

As Phrogz mentions in the comments, it's a common idiom in Ruby to track class-level data with an instance variable on the class itself. This can be a tricky subject to wrap your mind around, and there is plenty of additional reading on the subject, but think about it as modifying the Class class, but only the instance of the Class class you're working with. An example:

class Polygon
class << self
attr_accessor :sides
end
end

class Triangle < Polygon
@sides = 3
end

class Rectangle < Polygon
@sides = 4
end

class Square < Rectangle
end

class Hexagon < Polygon
@sides = 6
end

puts "Triangle.sides: #{Triangle.sides.inspect}" # 3
puts "Rectangle.sides: #{Rectangle.sides.inspect}" # 4
puts "Square.sides: #{Square.sides.inspect}" # nil
puts "Hexagon.sides: #{Hexagon.sides.inspect}" # 6

I included the Square example (which outputs nil) to demonstrate that this may not behave 100% as you expect; the article I linked above has plenty of additional information on the subject.

Also keep in mind that, as with most data, you should be extremely careful with class variables in a multithreaded environment, as per dmarkow's comment.

What does mean in Ruby?

It can have 3 distinct meanings:

'<<' as an ordinary method

In most cases '<<' is a method defined like the rest of them, in your case it means "add to the end of this array" (see also here).

That's in your particular case, but there are also a lot of other occasions where you'll encounter the "<<" method. I won't call it 'operator' since it's really a method that is defined on some object that can be overridden by you or implemented for your own objects. Other cases of '<<'

  • String concatenation: "a" << "b"
  • Writing output to an IO: io << "A line of text\n"
  • Writing data to a message digest, HMAC or cipher: sha << "Text to be hashed"
  • left-shifting of an OpenSSL::BN: bn << 2
  • ...

Singleton class definition

Then there is the mysterious shift of the current scope (=change of self) within the program flow:

class A
class << self
puts self # self is the singleton class of A
end
end

a = A.new
class << a
puts self # now it's the singleton class of object a
end

The mystery class << self made me wonder and investigate about the internals there. Whereas in all the examples I mentioned << is really a method defined in a class, i.e.

obj << stuff

is equivalent to

obj.<<(stuff)

the class << self (or any object in place of self) construct is truly different. It is really a builtin feature of the language itself, in CRuby it's defined in parse.y as

k_class tLSHFT expr

k_class is the 'class' keyword, where tLSHFT is a '<<' token and expr is an arbitrary expression. That is, you can actually write

class << <any expression>

and will get shifted into the singleton class of the result of the expression. The tLSHFT sequence will be parsed as a 'NODE_SCLASS' expression, which is called a Singleton Class definition (cf. node.c)

case NODE_SCLASS:
ANN("singleton class definition");
ANN("format: class << [nd_recv]; [nd_body]; end");
ANN("example: class << obj; ..; end");
F_NODE(nd_recv, "receiver");
LAST_NODE;
F_NODE(nd_body, "singleton class definition");
break;

Here Documents

Here Documents use '<<' in a way that is again totally different. You can define a string that spans over multiple lines conveniently by declaring

here_doc = <<_EOS_
The quick brown fox jumps over the lazy dog.
...
_EOS_

To distinguish the 'here doc operator' an arbitrary String delimiter has to immediately follow the '<<'. Everything inbetween that initial delimiter and the second occurrence of that same delimiter will be part of the final string. It is also possible to use '<<-', the difference is that using the latter will ignore any leading or trailing whitespace.



Related Topics



Leave a reply



Submit