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

class << Awesomeness
What is this << for? I searched, but the results only tell me about string concatenation...

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.

<< is the syntax for "Singleton class definition". Here is an example of where/how it is "typically" used.
In a = "abc"; a << "xyz" it is the syntax for "appending data" (to string, array etc.)

If you want inheritance (based on your question title), you want a single <:
class Awesome < ParentAwesomeness
The code you provide isn't valid ruby:
class Awesomeness
end
class Awesome << Awesomeness
end
SyntaxError: (irb):3: syntax error, unexpected tLSHFT, expecting '<' or ';' or '\n'

Related

Why does this Ruby method need to be a class level method?

Here's a classic fizzbuzz in Ruby:
class PrimeChecker
def print_em
1.upto 100 do |fizzbuzz|
if (fizzbuzz % 2) == 0 && (fizzbuzz % 5) == 0
puts "fizzbuzz: " + fizzbuzz.to_s
elsif (fizzbuzz % 5) == 0
puts "fizz: "+fizzbuzz.to_s
elsif (fizzbuzz % 2) == 0
puts 'buzz: ' + fizzbuzz.to_s
else
puts "-" + fizzbuzz.to_s
end
end
end
end
PrimeChecker.print_em
When I execute this, I get this error:
undefined method 'print_em'.
I change the method to self.print_em and it works. Does this mean it's a class method (I think so)? Was the method "not found" before because I can only call such methods in a class on actual instances of the object? If I wanted it to be a instance method what is the syntax for that? I'm trying to understand Ruby, classes and methods better.
Class methods are just that: called on the class. Whereas instance methods are called on an instance of that class. An example is more useful:
class Foo
def self.bar
"This is a class method!"
end
def bar
"This is an instance method!"
end
end
Foo.bar # => "This is a class method!"
foo = Foo.new # This creates "foo" to be a new instance of Foo
foo.bar # => "This is an instance method!"
Note that "class methods" in Ruby are actually methods on the class object's singleton. This is a rather difficult concept to explain, and you can read more about it if you'd like.
It's not a class method as written; you need to run it with an instance of PrimeChecker:
pc = PrimeChecker.new
pc.print_em
Using self. turns it into a class method, runnable with the syntax you show.
It doesn't need to be a class method, it's just that that's how you're trying to execute it.
Q: When I run ruby.rb I get undefined method 'print_em'. I change the method to self.print_em and it works. Does this mean it's a class method (I think so).
A: Yes. class Bar; ... def self.foo defines a class method foo for class Bar.
Q: Was the method "not found" before because I can only call such methods in a class on actual instances of the object?
A: You were first defining it as an instance method. In that case, it is only available to instances of the class.
Q: If I wanted it to be a instance method what is the syntax for that?
A: The way you had it originally: class Bar; def foo defines instance method foo for class Bar
Yes, you are completely correct. Currently, the way you define it, you can evaluate the method with:
PrimeChecker.new.print_em
The reason def self.my_awesome_method defines it on the class side is because the stuff inside
class MyAwesomeClass
end
is being executed in the context of MyAwesomeClass. It's all Ruby code, as you can see! This enables you to do things like this:
class MyAwesomeClass
puts "Hello from innards of #{self}!" #=> Hello from the innards of MyAwesomeClass!
end
Method definitions will also only work if you call them after the definition location, for example:
class MyAwesomeClass
my_awesome_method # produces a nasty error
def self.my_awesome_method
puts "Hello world"
end
my_awesome_method # executes just fine
end
Hope this clears some things up.

# used inside a self method is doing what exactly?

I saw this in some code today.
class Foo
def self.bar
#myvar = 'x'
end
end
What exactly is this accessing? As far as I can tell, this isn't accessible form instance methods. What's this called (something google-able) as I cant seem to find examples of this anywhere else.
The #myvar syntax identifies myvar as an instance variable so the real question is this:
What is self inside a class method?
And the answer is "self is the class object". So, #myvar is an instance variable of the Foo class object. If you add another class method:
class Foo
def self.pancakes_house
#myvar
end
end
And then do this:
Foo.bar
puts Foo.pancakes_house
You'll see x on the standard output.
A class is also an object, so you are setting a instance variable in class Foo.
>> Foo.bar
>> Foo.instance_variable_get("#myvar")
=> 'x'
Now, for a typical use, add class << self; attr_accessor :myvar; end to your class and you can write:
>> Foo.bar
>> Foo.myvar
=> 'x'
For googling, this is sometimes called a "class instance variable". That is, an instance variable of an object that just happens to be a class.

Difference between instance_eval and class << self?

I can't seem to grasp the exact difference between these two "constructs". To my mind, the following small script should output the same thing three times:
class Example
puts self
class << self
puts self
end
instance_eval do
puts self
end
end
However, the output is:
Example
#<Class:Example>
Example
Here's my rationale:
Example is an instance of Class, so self in the class body refers to that;
class << obj sets self to whatever obj is in the given block, which in my case is the instance of Class that is Example (this is where I'm probably wrong);
instance_eval runs the block in the given instance, so, in my case it's pretty much the same as putting the code in the block directly in the class body.
My current guess is that class << self inserts a ghost class between Example and Class and sets self to that, but the output of #<Class:Example> is not confirming that at all.
So what is wrong with my rationale?
class << obj sets self to whatever obj is in the given block, which in my case is the instance of Class that is Example (this is where I'm probably wrong);
No, class << obj opens up the singleton class of obj. As you correctly pointed out, inside of a class declaration, self refers to the class itself, so, in this case, the "inner" self (i.e. the one being passed to puts) refers to the singleton class of Example.
In my opinion, class << self has been one of the most obnoxious bits of syntax in Ruby. People new to the language have little idea what it means, apart from cargo-cult conventions, and even those intimately familiar with the language have only a hazy understanding of what differentiates it from instance_method, as the two do seem to be remarkably similar.
Here's an example of two different ways of defining a class method:
class Example
class << self
def class_def
:class_def
end
end
instance_eval do
def instance_def
:instance_def
end
end
end
You can check that these work by calling the methods:
puts Example.class_def.inspect
# => :class_def
puts Example.instance_def.inspect
# => :instance_def
The difference is when you're dynamically creating methods using define_method since the binding does appear to be incorrect on the instance_eval version:
class Example
class << self
define_method(:class_def) do
:class_def
end
end
instance_eval do
define_method(:instance_def) do
:instance_def
end
end
end
This results in the instance_def method being defined, but not being bound to the class itself:
puts Example.class_def.inspect
# => :class_def
puts Example.instance_def.inspect
# => NoMethodError: undefined method ‘instance_def’ for Example:Class
The only reliable way to create dynamic methods is with class << self. The method instance_def appears to be created and discarded as it doesn't show up in Example.methods even inside that block.

Whats the difference between class_eval and class << className?

I am a Ruby starter. I found both of these are quite similar (in output), but i couldn't understand the difference in the below context. For example, I have a class
class Say
def self.hello
puts "hello"
end
end
and can be extended like this
class << Say
def hi
puts "hi"
end
end
and also like this
Say.class_eval do
def self.bye
puts "bye"
end
end
When should I use << and when class_eval?
class_eval doesn't really have anything to do with class << className.
A.class_eval do
...
end
is equivalent to
class A
...
end
with a few differences. class_eval uses a block (or a string, but ignoring that for the moment) which means it closes over the containing lexical scope. In other words you can use local variables from the surrounding scope. The common class block introduces a brand new scope. Likewise you can create the block and pass it to many different class_eval's, and the body of the block will be executed in the context of the class you are calling class_eval on.
class << className opens the singleton class of className, allowing you to define class methods.
class << A
def foo
...
end
end
Is the same as
def A.foo
...
end
Note that they are oly class methods if A happens to be a class (almost) all objects in ruby have singleton classes and you can define methods for them using either of those two syntaxes. The advantage of class << obj is mainly if you're defining many singleton methods in one go.
As already said class_eval has really not much to do with
class <<self
even if they seem to do the same thing in your example (while the effect is similar it does not do the same, there are subtle differences).
Here is another example where the usage of the second form is far more clearer:
class A
end
a = A.new
b = A.new
class <<b
def say_hi
puts "Hi !"
end
end
b.say_hi # will print "Hi !"
a.say_hi # will raise an undefined method
a and b are both objects of the same class A but we added a method to the metaclass of b so the method say_hi is only available to the b object.

In Ruby are there any related applications of the syntax: class << self ... end

class << self
attr_accessor :n, :totalX, :totalY
end
The syntax above is used for defining class instance variables. But when I think about what syntax implies, it doesn't make any sense to me, so I'm wondering if this type of syntax is used for any other types of definitions. My point of confusion here is this:
class << self
The append operator normally means "add what's on the right to the object on the left". But in the context of this block, how does that add up to "put the contents of this block into the definition of the class instance rather than the instance"?
For the same reason I'm confused as to why in one context class << self can define class instance variables while in another it seems to create class variables such as here:
class Point
# Instance methods go here
class << self
# Class methods go here
end
end
in Ruby you can reopen existing classes and add methods. That is, you can say:
class Foo
def bob
return "hello from bob"
end
end
these methods get stored somewhere in an internal dictionary (maybe an instance variable) of the Foo-class (which is just an instance of the Class-class and therefore has instance variables)
But the suprising thing is, that you can also add methods to instances of existing objects
foo = Foo.new
foo2 = Foo.new
def foo.fred
return "I am fred"
end
foo.fred #=> "I am fred"
foo2.fred #=> NoMethodError
but Where is this method actually stored?
Turns out Ruby creates a new class behind the scenes (sometimes called singleton class, metaclass or eigenclass) which gets inserted in the inheritance heirarchy between the Foo-class and its instance.
So the inheritance relationship looks like that:
foo < (eigenclass of foo) < Foo < Class
(if you say foo.superclass you will not see the singleton class)
the class << X-syntax is a way to get to this special class, so that you can manipulate it directly. The following code blocks are exactly equivalent:
def foo.bar
return "xy"
end
# is exactly the same as
class << foo
def bar
return "xy"
end
end
So the similarity between class Foo < Bar and class << Foo is not accidental, there is inheritance going on in both.
Think of class << X as "open up the metaclass of X"
The thing to remember in Ruby is that classes themselves are just objects. (Instances of the class Class) so if you say:
class Foo
class << self
def k
return "x"
end
end
end
(self is bound to Foo in this code block) so k is an instance method of the eigenclass of Foo, which makes it a class method for Foo
all this is explained more clearly in the chapter about classes of the Pickaxe (the web version does not contain the diagrams, unfortunately) and _whys Seeing Metaclasses Clearly
Think of the class as containing a dictionary of members including all the accessors and instance variables. When you tell the class to "append" to "itself", you're saying "add these to the dictionary of class members."
I'll grant the notation is a little hinky, though.
it's actually confusing to think of it in terms of an "append" operator. a better way to look at it is that just as class Foo opens up class Foo, that is, it sets 'self' to the class object Foo, creating it if necessary, so class << self opens up the eigenclass of the current 'self' object. note that it is not limited to self - for any object bar, you can say class << bar to open up the eigenclass of that object.
class A
def hello
print "hello world"
end
end
a = A.new
b = A.new
class << a
def goodbye
print "goodbye cruel world"
end
end
a.hello
b.hello
a.goodbye
b.goodbye

Resources