Ruby methods called at top of classes - ruby

I've seen this a lot in Ruby (started using Ruby for the first time a couple years ago):
class MyAwesomeClass
another_method
def initialize; end
end
And I can't get my head around what type of method another_method is...
Looking at examples, it's sometimes declared as a class method, but usually you call class methods in your code like this:
AnotherClass.another_method
And most importantly you call your methods regardless if they are from another class, module, or inherited class inside another method of your class you use them. For example:
module SomeModule
def some_method; end
end
class AnotherClass
private
def another_method; end
end
class YetAnotherClass
self.yet_another_method; end
end
class MyAwesomeClass < AnotherClass
include SomeModule
def initialize
some_method # method from my included module
another_method # method inherited from AnotherClass
YetAnotherClass.yet_another_method # class method called directly
end
end
So what are these methods that can be called at the top of a class and NOT called inside of another method as my examples above?
Are you able to just call class methods inside another class (that it inherits from) outside of your method calls?

I can't get my head around what type of method another_method is...
There is only one type of method in Ruby: every method in Ruby is an instance method of some module. There is no other type of method.
We may sometimes talk about "class methods" or "singleton methods", but that is just a convenient way of talking about a particular way to use methods. The methods themselves are no different.
Every method in Ruby is an instance method of some module. The question is simply: which module?
We are sometimes talking about class methods, but class methods don't really exist. Class methods are simply singleton methods of an object that happens to be an instance of the Class class.
There is absolutely no difference between
Foo = ''
def Foo.bar; end
and
class Foo; end
def Foo.bar; end
and
module Foo; end
def Foo.bar; end
We call the first one a "singleton method", the second one a "class method", and the third one a "module function", but there is actually no difference between the three. The only difference is that the first object is an instance of the String class, the second object is an instance of the Class class, and the third object is an instance of the Module class, that's it.
Actually, I must confess something: I lied. I wrote that class methods are simply singleton methods of an object that happens to be an instance of the Class class, but in reality … singleton methods don't exist either.
A singleton method is simply a boring old normal instance method of the singleton class.
There is no difference between
foo = ''
def foo.bar; end
and
foo = ''
class << foo
def bar; end
end
There you have it: singleton methods are actually just instance methods of the singleton class, class methods are actually just instance methods of the singleton class of an object that is an instance of the Class class, module functions are actually just instance methods of the singleton class of an object that is an instance of the Module class.
It's just that "instance method of the singleton class of an object that is an instance of the Class class" is annoying to say and write all the time, so we say "class method" instead, knowing full well that there is no such thing.
Looking at examples, it's sometimes declared as a class method, but usually you call class methods in your code like this:
AnotherClass.another_method
Again, there is no such thing as a class method. There is exactly one kind of method, and they are always called the same way:
receiver.method(args)
If the receiver is self, then you can leave it out, and if you have no arguments, you can leave them out, too.
And most importantly you call your methods regardless if they are from another class, module, or inherited class inside another method of your class you use them.
That is not true.
In fact, in your own example, you are calling two methods outside of a method body: Module#private and Module#include, and you seem to have no trouble with those. Other methods that I am sure you have already called outside of a method body are Module#attr_accessor, Kernel#require, or Kernel#puts. In fact, in simple scripts, there is often not a single method definition body at all.
So what are these methods that can be called at the top of a class and NOT called inside of another method as my examples above?
They are instance methods just like any other instance methods, there is absolutely nothing special about them.
Are you able to just call class methods inside another class (that it inherits from) outside of your method calls?
Since class methods don't exist, and these are simply instance methods just like every other instance method, the method lookup algorithm is of course also just the method lookup algorithm for instance methods:
Start with the private internal hidden __klass__ pointer of the receiver. If you can't find the method there …
Get the private internal hidden __superklass__ pointer and repeat.
And that's it. (Yes, okay, there is a tiny bit more to it: if you come to a point where there is no __superklass__ pointer, then you try again with method_missing and the name of the method as an argument, and if you also cannot find that, then you raise a NoMethodError.)
So, let's try that in your example:
class MyAwesomeClass
another_method
end
Okay, first off: what is the receiver? Well, if no receiver is given, then the receiver is always implicitly self. Now, what is self here?
A ha! That is actually the most important question in Ruby, always. At any point in Ruby, you must always know what self is.
Well, we know that inside of a method body, self is the receiver of the message send. So, we can guess: what would make the most sense for self inside of a class definition. The class itself, of course! Let's test that:
what_is_self = class MyAwesomeClass
self
end
p what_is_self
# MyAwesomeClass
Well, looks like we're right. Okay, we know the receiver of the message send is MyAwesomeClass, so what is the first step in our algorithm? We get the private internal hidden __klass__ pointer.
We cannot actually do that in Ruby (it is a private internal hidden implementation detail of the Ruby implementation). But let me assure you that is pretty much always going to be the singleton class. (There are some objects which cannot have singleton classes, and some Ruby implementations optimize the creation of singleton classes so that they are only created when needed, but for all intents and purposes, we can assume that the __klass__ pointer is always the singleton class.)
We look inside the singleton class, and we find no definition of the method another_method. So, we move to the second step of the algorithm: we get the __superklass__ of the singleton class.
The __superklass__ of the singleton class is usually going to be the class of the object. So, in this case, the object is MyAwesomeClass, which is a class, so the class of MyAwesomeClass and the __superklass__ of the singleton class is going to be Class.
Again, we look inside Class and we don't find another_method. Ergo, we get Class's __superklass__, which is Module. We also don't find another_method here, so we move on to Object, which also doesn't have another_method.
Now, it gets interesting again, because Object's __superklass__ pointer is actually Kernel and not BasicObject as you might have thought. (More precisely, it is an include class which shares its method table with the Kernel module, since Kernel is not a class at all and thus cannot be a superclass.)
Kernel also doesn't have a method named another_method, so we get Kernel's __superklass__ (again, technically we are talking about an include class that proxies Kernel and not Kernel itself), which is BasicObject. Finally, BasicObject does not have a __superklass__.
Which means we start aaaaaaaaaaaall the way back from step #1 again, but this time as-if you had written
class MyAwesomeClass
method_missing(:another_method)
end
We do the whole song-and-dance again, and we also never find a method until we get to the very top, to BasicObject, which has a method_missing that roughly looks like this:
class BasicObject
def method_missing(meth, *args)
raise NoMethodError, "undefined method `#{meth}' for #{inspect}", meth, args, receiver: self
end
end
So, if you want your call to another_method to not fail, it needs to be defined anywhere along the whole chain we just walked up:
In MyAwesomeClass's singleton class
In a module that MyAwesomeClass extends
In Class
In a module that Class includes
Or in a module included by that module
In Module
In a module that Module includes
Or in a module included by that module
In Object
In Kernel
Or another module that Object includes
Or in a module that Kernel includes
In BasicObject
In a module that BasicObject includes
Or in a module included by that module
Or maybe the Ruby implementation you are using has an implementation-specific superclass of BasicObject (e.g. MacRuby has Objective-C's NSObject as the superclass of BasicObject)

To illustrate difference between different type of methods, consider this example:
class Foo
puts 'method called outside of method'
def initialize
puts 'initialize called'
end
def instanse_method
puts 'instance method called'
end
def self.clazz_method
puts 'class method called'
end
end
Foo
foo = Foo.new
foo.instanse_method
Foo.clazz_method
What will be the output?
method called outside of method
initialize called
instance method called
class method called
So what are these methods that can be called at the top of a class and NOT called inside of another method as my examples above?
As you can see, any method can be called before initialize method. It's executed when class is loaded.
Just calling
Foo
would be sufficient enough to output:
method called outside of method
(but notice that it was not called multiple times)
Looking at examples, it's sometimes declared as a class method, but usually you call class methods in your code like this: AnotherClass.another_method
It's like static function in PHP. In my example, it's Foo#clazz_method.
And most importantly you call your methods regardless if they are from another class, module, or inherited class inside another method of your class you use them
Usually, you have to include a file that define another class before using its method. But most frameworks like Ruby on Rails, have already built-in autoloading system, so it looks like it's working magically without explicit require or include. But there are times when RoR does not know where your custom classes are. In this case, you have to require the file explicitly before you use it. Well, usually in the beginning of the file.

It'll be easier to understand by looking at it in action.
# Step 1
# Run this in IRB
class MyClass
def self.another_method
puts "Executed when class is loaded to memory"
end
end
# Step 2
# Now when you run the following in IRB after that, its going to execute the
# class method which was defined in its parent class (MyClass)
class MyAwesomeClass < MyClass
another_method # Executed ONCE when the class is loaded to memory for the first
def initialize; end
end
# Now if you instantiate MyAwesomeClass though, it will not print the same as of
# Step 2 as class method :another_method already has been executed when class
# was loaded
awesome1 = MyAwesomeClass.new
The body of a class will be interpreted and executed sequentially & behaves much like you'd expect it inside an instance method. Try putting a puts "Hello World" in the body of your class definition like so:
class MyClass
# Executes when the class is defined in IRB(Loaded to memory)
puts "Hello World"
end

Related

How to define module methods like those in module Math?

The methods in Math can be invoked like a class method:
Math.cos(0)
but also can be include-d like instance method:
include Math
cos(0)
In contrast, the following modules can be invoked in one way but not the other:
module Foo
def bar
end
end
Foo.bar() # NoMethodError for this call
include Foo
bar() # but this call is fine
Singleton method:
module Foo
def self.bar
end
end
Foo.bar() # this call is fine
include Foo
bar() # but not this one
Any idea how to write a module like Math?
There're a few ways to get singleton methods, so I'm going to go over those first. We'll get to the part that lets the include Math work in a minute. So, first, if you're in a module or class body, you can define a singleton method as a method of self, like so:
module Foo
# Define bar as a method on self (the Foo module), thereby making
# it a singleton method.
def self.bar
"baz"
end
end
Alternatively, you can define them as methods on a module or class's singleton class:
module Foo
# Opens the singleton class of self (the Foo module). This makes
# bar a singleton method (see Module#define_singleton_method for
# some more on that).
class <<self
def bar
"baz"
end
end
end
include Math, Having Your Methods, and Eating Them Too
Thirdly, if you want methods as both instance and singleton methods, you can use extend. This allows you to include the module somewhere and call its methods without qualification or at least with differing qualification, depending on where you include the module (sort of -- that's beyond the scope of this, though). You can also extend self or extend using another module (containing instance methods) to add them as singleton methods when in a module or class body. This might sound more complicated than it probably looks:
module Foo
def bar
"baz"
end
# Extending self will add the instance methods of self as
# methods on the object self -- which happens to be a module,
# so you basically get class methods from the instance methods.
extend self
end
This last case allows you to also include the module in another module or class and gain bar as an instance method as well, so what you do depends on what you need. In general, I prefer the first route if I'm just defining a singleton method and it's all I'll need. The second option is more or less equivalent, but also allows you to use alias_method and so on. Qualified access is next to godliness, as far as I'm concerned.
The third option, however, — using extend self — is good for doing what you're asking about with include Math, where you want to be able to both call a function as a singleton method (Math.cos(0)) and include the module to access and call the methods without qualifying them with the module name (cos(0)). If you want that, you can do one of the following:
Define the method twice, both as a singleton method and as an instance method. This is not preferrable.
Define them in another module and both include and extend using that module. This is handy if you want to use the module in multiple places.
extend self. Extending using self is probably the best choice here, since it's simple, reduces duplicate code, and it's sufficient for the purpose of the question.
So there you go, instance methods and singleton methods living side-by-side in harmony, just like Holan and Hamlet.
That's what Module#module_function is for.

why are metaclasses created in ruby?

I m trying to understand the Ruby Object Model. I understood that the instance methods are saved in the class rather than in the objects of the class because it removes redundancy. I read that whenever a class is created, a metaclass is created too for the newly created class. the metaclass stores the class methods. ie the singleton methods of the class are located in the metaclass. eg
class MyClass
def hi
'hi object'
end
def self.bye
'bye singleton method'
end
end
for the above MyClass, a metaclass (say #MyClass) is created too. now the method 'hi' is an instance level method and can be called on all the objects of MyClass. method 'bye' is a singleton method of MyClass and it resides in the #MyClass. the reason (i think so) why 'hi' is saved in MyClass rather than all the objects of MyClass is because it avoids redundancy. But we cant have more than one classes named MyClass. So why not store 'bye' in MyClass rather than in #MyClass, since we cant have more than one MyClass. I have absolutely no idea why this is the way it is and i m just trying to understand the reason behind it.
-----UPDATE----
metaclass store the class information like the singleton methods and other stuff. But since a class is a singleton object(its an instance of class Class and is alone of its type) then why not save all the information in the class itself rather than the metaclass.
Just to be super duper clear.
Here is a quick ruby script that explains the question:
#!/usr/bin/env ruby
puts ObjectSpace.count_objects[:T_CLASS] #>> 471
class X
def self.foo
end
def bar
end
end
puts ObjectSpace.count_objects[:T_CLASS] #>> 473
This is what the OP meant by "ObjectSpace.count_objects[:T_CLASS] increments the count by 2." Let's call the extra class the singleton class of X, because that appears to be what Ruby calls it internally.
irb> X
=> X
irb> X.singleton_class
=> <Class: X>
Notice that the #foo method is an instance method of X.singleton_class, not X.
irb> X.instance_methods(false)
=> [:baz]
irb> X.singleton_class.instance_methods(false)
=> [:foo]
So why is :foo stored in X.singleton_class instead of X? Isn't there only ever going to be one X?
I believe the main reason is for consistency. Consider the following, simpler scenario concerning plain instance objects.
car = Car.new
def car.go_forth_and_conquer
end
As #mikej explained superbly, this new method is stored in car's singleton class.
irb> car.singleton_class.instance_methods(false)
=> [:go_forth_and_conquer]
Classes are Objects
Now, classes are objects too. Each class is an instance of Class. Thus, when a class (say, X) is defined, ruby is really creating an instance of Class, and then adding methods to the instance (similar to what we did to car above.) For example, here is an alternative way to create a new class
Car = Class.new do
def go_forth_and_conquer
puts "vroom"
end
end
Car.new.go_forth_and_conquer
Therefore, it is much easier to just reuse the code and do it the same way (i.e. keep foo in X.singleton_class.) This probably requires less effort and will lead to fewer surprises, so no one will ever need to write code to handle Class instances differently from other instances.
Probably Doesn't Matter
You might be thinking that if Ruby did not have singleton classes for instances of Class, there could be some memory savings. However, it sounds to me that where bar is actually stored is an implementation detail that we probably shouldn't count on. Rubinius, MRI, and JRuby could all store methods and instances differently, as long as the behavior is consistent. For all we know, there could be a reasonable implementation of Ruby that doesn't eagerly create singleton classes for class objects, for the exact same reasons you outlined, as long as the overall behavior conforms to the ruby spec. (E.g. an actual singleton class doesn't exist until the #singleton_class method is first invoked.)
This isn't quite an answer to your question, but it might be useful. Two things to think about that might help:
metaclass is not really a good name for what's going on here when you think of how the meta prefix is used in other scenarios. eigenclass which you will see used in other documentation is probably a better name, meaning "an object's own class"
It's not just classes that have an eigenclass, every object does
The eigenclass is used to store methods that are specific to a particular object. e.g. we can add a method to a single String object:
my_string = 'Example'
def my_string.example_method
puts "Just an example"
end
This method can only be called on my_string and not on any other String object. We can see that it is stored in my_string's eigenclass:
eigenclass = class << my_string; self; end # get hold of my_string's eigenclass
eigenclass.instance_methods(false) # => [:example_method]
Remembering that classes are objects, in this context, it makes sense that the methods specific to a particular class should be stored in that class's eigenclass.
Update: actually, there is an eigenclass for the eigenclass. We can see this more easily if we add eigenclass as a method to Object:
class Object
def eigenclass
class << self
self
end
end
end
and then we can do:
irb(main):049:0> my_string.eigenclass
=> #<Class:#<String:0x269ec98>>
irb(main):050:0> my_string.eigenclass.eigenclass
=> #<Class:#<Class:#<String:0x269ec98>>>
irb(main):051:0> my_string.eigenclass.eigenclass.eigenclass # etc!
=> #<Class:#<Class:#<Class:#<String:0x269ec98>>>>
whilst this seemingly creates an infinite regress, this is avoided because Ruby only creates the eigenclasses on as they are needed. I think the name "metaclass" really is a source of part your confusion because you are expecting a "metaclass" to hold some kind of information that it actually doesn't.
The reason really boils down to what self is. For any given method, self is an instance of the object that the method is defined one.
In an instance method, stored on MyClass, self will be the instance of MyClass that you called #hi from. In a class method, self will be the instance of the metaclass (that is, the class itself). Doing it with the metaclass means that the concept of self is unchanged, even when operating on a class, which is itself just a singleton instance of its metaclass.
As per The Ruby Programming Language the class methods, are infact singleton methods on an instance of the class that got same name as the class.
Class Foo
def self.bar
"Am a class method"
end
end
here method self.bar can be depicted as a singleton method on an instance Foo of type Class Foo.
#the following code is just to explain on what actually are class methods called
Foo.bar #=> "Am a class method"
#the call is done on an instance of class Foo which got ref name Foo
We can go on adding more class/singleton/metaclass methods on Foo by
class<<Foo
def self.another_bar
"Am another class method"
end
end
Foo.another_bar #=>"Am another class method"
More formally singleton methods are defined as instance methods of an anonymous eigenclass/meta class.
Though conceptually wrong we can assume classes are objects in this context, so as to have a better grasp.
This concept is there to bring in true Object Oriented - ness in all levels of the language. Objective-C implements class methods in a similar fashion.
In Obj-C metaclasses bails out as classes which contain information about the classes it meta. And the principles of inheritance do apply for meta-classes as well, there super class is its classe's superclasse's metaclass and climbs up so until it reaches the base object, whoe's metaclass is the metaclass itself. More reading on this can be done here.

Understanding Ruby Inheritance

I've been reading the Well Grounded Rubyist and it mentions how a class inherits the instance methods of its super class so that objects of the class will be able to call those instance methods. Here's an example:
class C
def run_instance_method
puts "This is an instance method."
end
def C.run_class_method
puts "This is a class method."
end
end
class D < C
end
Based on what I've read, it's always been described that class D would inherit just the instance methods of class C (in which case, the C::run_class_method would not be inherited by D). However, after running the above code, I notice that:
D.run_class_method # => "This is a class method."
Here's my guess as to why this is happening and please let me know if this is the correct understanding. If there is an instance d of class D and you try to run d.run_instance_method, that object will search its method-lookup path and see if that method is defined in its singleton class, its own class, or in its superclasses. Since run_instance_method is defined in class C, no issues will occur and run_instance_method will be called. For the class object D (which is a subclass of C and Object), if D.run_class_method is called, it'll again check the method lookup path for the D class object. Again, Ruby will find it in the class object C.
Is this reasoning accurate?
Class methods may be inherited and overridden just as instance methods can be. If your parent class defines a class method, the subclass inherits that method. That is, if your subclass does not define it's own class method, then it inherits from it's superclass.
As a recommendation: when invoking a class method with an explicit receiver, you should avoid relying on inheritance. Always invoke the class method through the class that defines it. Otherwise, it would be very difficult for someone who relies on your code to find the parent class which defines the class method.
Referring back to your original assumption: the invocation of a class method from a subclass it's possible because the class methods are instance methods of the eigenclass.
class C
# instance methods goes here
class << self # open the eigenclass
# class methods go here as instance methods of the eigenclass
end
end
In general, it's clearer to define class methods as individual singleton methods without explicitly opening the eigenclass.
For a clear explanation read The Ruby Programming Language by David Flanagan and Yukihiro Matsumoto
Not very exactly. There is another concept hidden here, called metaclass or eigenclass. The class method is inherited from eigenclass. See Ruby Hacking Guide for more information about it. ( Just search for "class methods" in the page if you don't want to read them all. )

Ruby mixin override method clarification

I've just faced this behavior I don't really understand.
module M
def foo
"module_foo"
end
end
class C
def foo
"class_foo"
end
include M
end
puts C.new.foo
Why does C.new.foo actually return class_foo ? I was pretty much sure that method should be overridden by the one in module. Another thing, replacing "class_foo" with super makes C.new.foo return `"module_foo"
That actually looks like module is somehow included before the class instance method is defined. Could you please clarify?
From Programming Ruby section on mixins:
In fact, mixed-in modules effectively behave
as superclasses.
So what you experience is normal.
your Module M is a superclass of your class C
Therefore your foo method in class C overrides the foo method in module M
Here's how ruby does method lookup:
receiver's singleton class;
receiver's class;
any included modules methods;
repeat lookup in in the receiver's superclass;
if no method was found at all, method_missing call;
You can find more details here: http://ruby-metaprogramming.rubylearning.com/html/ruby_metaprogramming_2.html
Therefore, to find a method, Ruby goes in the receiver's class, and from there it climbs the ancestors chain until it finds the method.
This behavior is also called the "one step to the right, then up"
rule: Go one step to the right into the receiver's class, and then up
the ancestors chain, until you find the method. When you include a
module in a class (or even in another module), Ruby creates an
anonymous class that wraps the module, and inserts the anonymous class
in the chain, just above the including class itself.

How do I get module mixins to work for static methods?

Lets say I have two modules. Is it possible to include a module inside another one that would behave like a mixin?
For example:
module A
def self.foo
puts "foo"
bar
end
end
module B
include A
def self.bar
puts "bar"
end
end
B.bar
B.foo
Edit: I realized I originally copied the code down wrong. The methods need to be static. The corrected code is above(and does not work).
As you've learned it doesn't work but why it doesn't work is a really good lesson about the Ruby object model.
When you create an instance of an object what you have created is a new object with a set of instance variables and a pointer to the class of the object (and a few other things like an object ID and a pointer to the superclass) but the methods themselves are not in the instance of the object. The class definition contains the list of methods and their code (and a pointer to its own class, a pointer to its superclass, and an object ID).
When you call a method on an instance Ruby looks up the class of the instance and looks in that class's method list for the method you called. If it doesn't find it then it looks in the class' superclass. If it doesn't find it there it looks in that class' superclass until it runs out of superclasses. Then it goes back to the first class and looks for a method_missing method. If it doesn't find one it goes to the superclass and so on till it gets to the root object where it's designed to raise an error.
Let's say for instance you have a class Person and you make an instance of the class with the variable bubba like this:
class Person
attr_accessor :dob, :name
def age
years = Time.now.year - #dob.year
puts "You are #{years} year#{"s" if years != 1} old"
end
def feed
puts "nom, nom, nom"
end
end
bubba = Person.new
bubba.name = "Bubba"
bubba.dob = Time.new(1983,9,26)
The class diagram would look something like this:
So what's happening when you create a static method, a class/module method? Well, remember that almost everything is an object in Ruby and a module definition is an instance of the class Class. Yep, that code you type out is actually an instance too, it's live code. When you create a class method by using def self.method_name you are creating a method in the instance of the object that is the class/module definition.
Great, so where's that class method being defined at you ask? It's being defined in an anonymous class (aka singleton, eigen, ghost class) that is created for exactly this reason.
Going back to our Person class what if we add a class method on the instance bubba like so:
def bubba.drive_pickup
puts "Yee-haw!"
end
That method gets put into a special singleton class created just for that instance and the singleton's superclass is now the Person class. This makes our method calling chain look like this:
Any other methods defined on the instance object bubba will also be put into that singleton class. There's never more than one singleton class per instance object.
So, to wrap it all up the reason why it doesn't work is the static methods in the modules are being defined in the singleton class for the instance of the module definition. When you include or extend from the module you are adding a pointer to the method table of the module but not the method table of the instance object of the singleton class for the module.
Think of it this way: If you create an instance x of type Z and an instance y of type Z should x know about y? No, not unless specifically told about it. So too your module that mixes in another module should not know about some other object that just happens to have that first module as its superclass.
For a much better explanation of the Ruby object model watch this awesome free video by the amazingly erudite Dave Thomas (no, not the guy from Wendy's):
http://scotland-on-rails.s3.amazonaws.com/2A04_DaveThomas-SOR.mp4
After watching that video I bought Dave Thomas's whole series on the Ruby object model from Pragmatic and it was well worth it.
P.S. Anyone please feel free to correct me on anything I forgot; like what's specifically in an object.
Use extend instead of include to add class methods.
module A
module ClassMethods
def foo
puts "foo"
puts bar
end
end
extend ClassMethods
end
module B
extend A::ClassMethods
def self.bar
puts "bar"
end
end
B.bar
B.foo
The exact code you posted works exactly like you want to. So, the answer is Yes.
Would it have been really that hard to just execute it yourself?

Resources