Ruby Class Inheritance: What Is '<<' (Double Less Than)

Ruby class inheritance: What is ` ` (double less than)?

While it's true that class << something is the syntax for a singleton class, as someone else said, it's most often used to define class methods within a class definition. But these two usages are consistent. Here's how.

Ruby lets you add methods to any particular instance by doing this:

class << someinstance
def foo
"Hello."
end
end

This adds a method foo to someinstance, not to its class but to that one particular instance. (Actually, foo is added to the instance's "singleton class," but that's more or less an implementation quirk.) After the above code executes, you can send method foo to someinstance:

someinstance.foo   => "Hello."

but you can't send foo to other instances of the same class. That's what << is nominally for. But people more commonly use this feature for syntactic gymnastics like this:

class Thing
def do_something
end

class << self
def foo
puts "I am #{self}"
end
end
end

When this code -- this class definition -- executes, what is self? It's the class Thing. Which means class << self is the same as saying "add the following methods to class Thing." That is, foo is a class method. After the above completes, you can do this:

t = Thing.new
t.do_something => does something
t.class.foo => "I am Thing"
t.foo => NoMethodError: undefined method `foo'

And when you think about what << is doing, it all makes sense. It's a way to append to a particular instance, and in the common case, the instance being appended to is a class, so the methods within the block become class methods.

In short, it's a terse way to create class methods within a class definition block. Another way would be to do this:

class Thing
def self.foo
# ...
end
end

Same thing. Your example is actually a syntax error, but if you understand how << is used with instances and the class keyword, you'll know how to correct it.

What does the ` ` (double less than) mean without an argument?

You can read it like this:

hidden_field_html << label_with_nested_checkbox

label_with_nested_checkbox is the argument being concatenated onto the end of hidden_field_html - they've split it over two lines for 'clarity'

Ruby (double less than) with instance variables

This code is a little confusing. The line:

games << game

is actually calling the method games, which returns @games. Then the << method is called on that result. There's some syntactic sugar in the Ruby parser that turns the << operator into a method call on the left operand, and the left operand is being evaluated before that happens.

Edit for more clarity:

The line could be written like this:

(games).<< game

or this:

(self.games).<< game

or:

(self.games) << game

all of which execute the games method.

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.

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



Related Topics



Leave a reply



Submit