Question | Click to View Answer |
Which class defines the Dog.about method? Demonstrate that this class includes the about method. class Dog
def self.about
'we bark'
end
end
|
Dog.about # a singleton method that's defined in Dog's singleton class:
Dog.singleton_class.instance_methods.include? :about # => true
Every Ruby object has a singleton class to store methods for a particular object. |
Add a method called my_singleton_class to the Object class that returns the singleton class of an object. Don't use the built in singleton_class method. |
class Object
def my_singleton_class
class << self
self
end
end
end
# Check the code works
Hash.my_singleton_class == Hash.singleton_class # => true
The 'class << obj' syntax changes the scope to the obj's singleton class. In this case self equals Object, so class << self changes the scope to Object's singleton class. |
What does the following code print? Explain. class NewYork
class << self
def greeting
"how you doin'?"
end
end
end
p NewYork.greeting
|
"how you doin'?"
The class << self syntax is used to access the scope of the NewYork singleton_class. Once inside the scope of the singleton_class, instance methods are the same as singleton_methods: NewYork.singleton_methods # => [:greeting]
|
What does the following code print? Explain. class Human
def Human.about; end
def self.generation; end
def hi; end
instance_eval do
def bye; end
end
end
p Human.singleton_methods
|
[:about, :generation, :bye]
There are several ways to define singleton methods. Notice that the Human#hi method is a regular instance method and is not a singleton method. |
Use the following code to demonstrate that singleton methods are the same as instance methods of the singleton class. class India
class << self
def info
"awesome country!"
end
end
end
|
India.singleton_methods == India.singleton_class.instance_methods(false) # => true
When false is passed as an argument to the instance_methods() method, it does not return any inherited methods. |
Describe the method lookup process for the following code. class Ghost; end
casper = Ghost.new
casper.boo
|
casper is an instance of the Ghost class and is the receiver of the message :boo in this example. The receiver first looks in its singleton_class for a method named :boo (the singleton class for the receiver is casper.singleton_class). If it does not find a method, it will continue up the ancestor chain to look for the method. Here is the ancestor chain for this example: ghost.class.ancestors # => [Casper, Object, Kernel, BasicObject]. If there are no classes that respond to the message, then method_missing is called.
|
Describe the method lookup process for the following code. class Alpha; end
Alpha.profit
|
In this example, the :profit message is sent to the receiver, Alpha. Alpha looks for methods corresponding to the :profit message in the following order: Alpha's singleton class, Object's singleton class, BasicObject's singleton class, Class, Module, Object, Kernel and finally BasicObject. method_missing is called if no methods correspond with the :profit message. The ancestors method can be used to view the method lookup path when the receiver is a class object: Alpha.singleton_class.ancestors
# => [#<Class:Alpha>, #<Class:Object>, #<Class:BasicObject>, Class, Module, Object, Kernel, BasicObject]
|
What is the superclass of BasicObject's singleton class? |
Class
BasicObject.singleton_class.superclass # => Class
The superclass of BasicObject is nil and it's important to notice that the superclass of BasicObject's singleton class is not nil. |
Explain the following statement: "Ruby does not have static class methods like some other programming languages." |
Ruby has singleton methods that function similarly to 'class' or 'static' methods in languages like Java, but the implementation is different. Ruby's 'class methods' are really just instance methods defined in the singleton class. Ruby doesn't have static methods like Java. |