I was just playing to see the instance method calls from the subclass and used the below code of my test:
class Animal
def bark
p "hukkhh"
end
end
#=> nil
class Cow < Animal
end
#=> nil
Cow.public_instance_method(:bark)
#=> #<UnboundMethod: Cow(Animal)#bark>
class Cow
bark
end
#=> NameError: undefined local variable or method `bark' for Cow:Class
# from (irb):11:in `<class:Cow>'
# from (irb):10
# from C:/Ruby193/bin/irb:12:in `<main>'
From that code I was confirmed that instance method can't be executed without the object instance of the respective class.
But then I tried below code:
def talk
p "hi"
end
#=> nil
Object.public_instance_method(:talk)
#=> #<UnboundMethod: Object#talk>
class Foo
talk
end
# prints: hi
#=> "hi"
Here the output made me confused with my first test code output.
Could anyone help me to understand the fact behind these above?
Method talk you defined is belongs to Object which is root of all objects. So talk method is available to all object in ruby.
def talk
p "hi"
end
Object.respond_to? :talk #=> true
Now, you defined class Foo which is also an ruby object.
Foo.is_a? Object #=> true
Foo.respond_to? :talk #=> ture
So talk is available to Foo class.
Now you define a class Animal with method bark
class Animal
def bark
p "hukkhh"
end
end
bark method you define is belong to Animal class for now as instance level method not class level. It means you need to create instance of class Animal to call bark.
Animal.respond_to? :bark #=> false
Object.respond_to? :bark #=> false
Animal.new.respond_to? :bark #=> true
Animal.respond_to? :talk #=> true #talk is available to Animal also because Animal is also object of Class
Animal.new.respond_to? :talk #=> true
Now you create class called Cow inheriting from Animal. So bark is available to Cow unless it is overridden.
class Cow < Animal
end
Cow.respond_to? :bark #=> false
Cow.new.respond_to? :bark #=> true
Cow.respond_to? :talk #=> true
Cow.new.respond_to? :talk #=> true
Cow.new.bark #=> "hukkhh"
So to call bark you need to create instance of class.
If you want to call a method of parent which is overridden in child use super
class Cow < Animal
def bark
super
#do your stuff
end
end
Cow.new.bark #=> "hukkhh"
Related
I know there have been other questions about the syntax class << self. Still, I did not find those answers clear enough. I have a background in Java/C#, C, so Ruby is kinda strange to me. I read that class << self refers to the singleton class. I find this kinda complex so I would like to understand what does the operator << do in this context and what is possible to put on both ends. I tried to write a simple code to help me understand this syntax (my questions are in the code):
class Self
def Self.selfTest
end
def onSelf
class << Self #I know this might be strange.
self
end
end
def onself
class << self
self
end
end
end
s = Self.new
onSelf = s.onSelf
onself = s.onself
#Here, i wanna know what kind of references are returned.
puts "onSelf responds to onSelf:#{onSelf.respond_to?(:onSelf)}"
puts "onSelf responds to selfTest:#{onSelf.respond_to?(:selfTest)}"
puts "onself responds to onSelf:#{onself.respond_to?(:onSelf)}"
puts "onself responds to selfTest:#{onself.respond_to?(:selfTest)}"
#Output:
#onSelf responds to onSelf:false
#onSelf responds to selfTest:false
#onself responds to onSelf:false
#onself responds to selfTest:true
#So, i conclude that the second one is a reference to a class. What is the first one???????
puts onSelf
puts onself
#Output
#<Class:Self>
#<Class:#<Self:0x007f93640509e8>>
#What does this outputs mean???????
def onSelf.SelfMet
puts 'This is a method defined on base class'
end
def onself.selfMet
puts 'This is a method defined on metaclass'
end
puts "Does Self Class respond to SelfMet? : #{Self.respond_to?(:SelfMet)}"
puts "Does Self Class respond to selfMet? : #{Self.respond_to?(:selfMet)}"
puts "Does Self instance respond to SelfMet? : #{s.respond_to?(:SelfMet)}"
puts "Does Self instance respond to selfMet? : #{s.respond_to?(:selfMet)}"
#Output
#Does Self Class respond to SelfMet? : false
#Does Self Class respond to selfMet? : false
#Does Self instance respond to SelfMet? : false
#Does Self instance respond to selfMet? : false
#Why won't they respond to defined methods????
Thanks
UPDATED:
Thank you all very much. I have read and tested a lot, so will leave a few considerations. I leave this for future reference and as so, i hope the Ruby experts can correct me if i am wrong. I realised that class << Self refers to the Self singleton class. So, the idiomatic class << abcd, starts the abcd singleton class context. I realised also that the hierarchy of a class singleton class is different from an object singleton class. The hierarchy of a class singleton class follows all singleton classes on a hierarchy. In this case:
singleton Self->singleton Object->Singleton basicobject ->class->module->object->kernel->basicObject
The object singleton class lies in a different kind of hierarchy:
Object singleton->Self->Object->kernel->basicObject
This explains this outputs.
In Ruby, every object has a singleton class. This singleton class has only one instance: the object it belongs to.
Since the singleton class has only ever one instance, and every object has its own singleton class, methods that are defined in this class can only be called on that specific object. Those methods are typically called singleton methods, although that is misleading: there's nothing special about those methods, they are just normal standard instance methods.
Here's an example:
foo, bar, baz = Object.new, Object.new, Object.new
class << foo; def quux; :foo end end
class << bar; def quux; :bar end end
foo.quux # => :foo
bar.quux # => :bar
baz.quux # NoMethodError
Classes are just objects like any other object. So, just like any other object, they have singleton classes. Methods defined in the singleton class of an object that happens to be a class are typically called class methods, although again, there's nothing special about them, they are just singleton methods of an object which happens to be a class, which in turn means they are just regular instance methods of a singleton class which belongs to an object which happens to be a class.
So, if you compare this to something like Java, you can see a duality: in Java, there is only one kind of class but there are two kinds of methods (instance and static). In Ruby, there is only one kind of method (instance) but it can be defined in different kinds of classes (regular and singleton).
I find this kinda complex so I would like to understand what does the operator << do in this context
That's just the syntax for opening up a singleton class as opposed to opening up a class.
and what is possible to put on both ends.
Well, on the left has to be the keyword class and on the right any expression that returns an object.
Perhaps this will help. If you add the following statements you will get the indicated results:
puts onSelf #=> #<Class:Self>
puts Self.singleton_class #=> #<Class:Self>
puts onSelf == Self.singleton_class #=> true
puts onself #=> #<Class:#<Self:0x007fe6330aab10>>
puts s.singleton_class #=> #<Class:#<Self:0x007fe6330aab10>>
puts onself == s.singleton_class #=> true
I see no point in defining a method whose receiver is a metaclass, but that is what you have done:
puts onSelf.SelfMet
#=> This is a method defined on Self's metaclass
puts onself.selfMet
#=> This is a method defined on s's metaclass
Obviously, onSelf (Self.singleton_class) responds to SelfMet (but not to selfmet), and onself (s.singleton_class) responds to selfmet (but not to Selfmet).
For Self to respond to SelfMet, the latter would have to be defined def Self.SelfMet... or def self.SelfMet.. (or one of a few other ways), but it is not.
Similiarly, for s to respond to selfMet, the latter would have to be defined as a normal instance method def selfMet... (in which case all other instances of Self would also respond to it) or defined in s's singleton class: def s.selfMet... (in which case other instances of Self would not respond to it).
In sum, the class Self responds to its singleton methods, as does the instance s respond to its singleton methods; the singleton classes of Self and s do not respond to those respective singleton methods.
The following may help you understand what's going on here. Each p self followed by #=> displays what follows #=> when the statement is executed by Ruby. Notice how the various statements, such as class Dog, class << self and others are used to change the value of self to what we want.
p self is your best friend when metaprogramming.
p self #=> main
class Dog
p self #=> Dog
def self.woof1
p self
end
def Dog.woof2
p self
end
p self #=> Dog
class << self
p self #=> #<Class:Dog>
p Dog.singleton_class #=> #<Class:Dog>
def woof3
p self
end
end
p self #=> Dog
def woof4
p self
end
end
p self #=> main
def Dog.woof5
p self
end
Dog.instance_eval do
p self #=> Dog
def woof6
p self
end
end
dog = Dog.new #=> #<Dog:0x007fe17b08cf00>
def dog.woof7
p self
end
dog.instance_eval do
p self #=> #<Dog:0x007fe17b08cf00>
def woof8
p self
end
end
p self #=> main
Dog.woof1 #=> Dog
Dog.woof2 #=> Dog
Dog.woof3 #=> Dog
Dog.woof5 #=> Dog
Dog.woof6 #=> Dog
dog.woof4 #=> #<Dog:0x007fe17b08cf00>
dog.woof7 #=> #<Dog:0x007fe17b08cf00>
dog.woof8 #=> #<Dog:0x007fe17b08cf00>
puppy = Dog.new #=> #<Dog:0x007fe17ba93a08>
puppy.woof4 #=> #<Dog:0x007fe17ba93a08>
puppy.woof7 #=> undefined method `woof7' for #<Dog:0x007fe5fb3e1d48>
puppy.woof8 #=> undefined method `woof8' for #<Dog:0x007fe5fb3e1d48>
It takes awhile to sort everything out. Even then, most of us need a refresher from time-to-time. Here's an excellent article on the subject. Also, look at some of the references in the comments there, especially Dave Thomas' presentation.
Lastly, have a look at Ruby's naming convention.
In Ruby, I can write,
Dog = Class.new
so here, Dog is an Object which is an instance of Class.
Also, I can write
fido = Dog.new
which is possible only if Dog is a Class.
Is Dog here a Class or an Object?
Everything in ruby is an Object (except for blocks). And Dog here is also a Class.
Dog = Class.new
fido = Dog.new
So the answer is: both.
Ask the object itself, to know where they belongs to, like below:
Dog = Class.new
fido = Dog.new
Dog.instance_of? Class #=> true
fido.instance_of? Class #=> false
fido.instance_of? Dog #=> true
Dog.superclass #=> Object
Dog.is_a? Object #=> true
Dog.is_a? Class #=> true
To look into in more detail see the Object model Documentation
I think you are making a mistake that some beginners repeatedly do. You are confusing the two meanings of "is":
A is an instance of B, and
A is a subclass of B.
With your case,
Dog is an instance of (but not a subclass of) Class, and
Dog is a subclass of (but not an instance of) Object.
So, in different senses, it is a Class and is an Object.
When they say "everything in Ruby is an Object", it does not mean that everything is an instance of Object. It means that everything is an instance of a (reflexive) subclass of Object.
First, install 'y_support' by typing gem install y_support in your command prompt. Then, in irb:
require 'y_support/name_magic'
class Animal
include NameMagic
end # You have created a new class
Animal.name #=> "Animal" -- the class is named Animal
class Dog < Animal
def speak; puts "Bow wow!" end
end #=> hereby, you have created a subclass of Animal class
Cat = Class.new( Animal ) do
def speak; puts "Meow!" end
end #=> this is another way of creating a subclass
Dog.name #=> "Dog" -- this is a class named Dog
And now
Fido = Dog.new #=> You have created a new Dog instance
Dog.instance_names #=> [:Fido] -- the instance is named Fido
Stripes = Cat.new #=> You have created a new Cat instance
Cat.instance_names #=> [:Stripes] -- the instance is named Cat
Animal.instances.size #=> 2 -- we have 2 animals thus far
Animal.instances.each do |animal| animal.speak end #=> Bow wow! Meow!
Let's create another dog:
Spot = Dog.new #=> Another Dog instance
Dog.instances.size #=> 2 -- we now have 2 dogs
Fido.class #=> Dog -- Fido is an instance of class Dog
Spot.class #=> Dog -- Spot is also an instance of class Dog
Fido.class.ancestors #=> The output shows you that Fido is also an Animal
Animal.instances.size #=> 3 -- together, we have 3 animals
Animal.instance_names #=> [:Fido, :Stripes, :Spot]
Animal.instance( :Fido ).speak #=> Bow wow!
Animal.instances.each &:speak #=> Bow wow! Meow! Bow wow!
Understood? Remember, in Ruby, never work without NameMagic.
I was playing with singleton class in my IRB. And doing so tried the below snippets.
class Foo ; end
#=> nil
foo = Foo.new
#=> #<Foo:0x2022738>
foo.define_singleton_method(:bar , method(:puts))
#=> #<Method: Object(Kernel)#puts>
Here above I just created a singleton method on instance of class Foo.
foo.bar("hi")
hi
#=> nil
foo.singleton_methods
#=> [:bar]
foo_sing = foo.singleton_class
#=> #<Class:#<Foo:0x2022738
foo_sing.is_a? Class
#=> true
foo_sing.instance_of? Class
#=> true
foo_sing.inspect
#=> "#<Class:#<Foo:0x1e06dc8>>"
In the above I tried to create a singleton class on instance of class Foo. And also tested if foo_sing holds reference to the singleton class on instance of class Foo.
foo_sing.methods(false)
#=> []
foo_sing.methods.include? :bar
#=> false
In the above I was looking if singleton_method bar is in the foo_sing or not.But found it is not present there.Then my question is - where does thosesingleton_method reside in Ruby?
foo_sing.new.methods(false)
#TypeError: can't create instance of singleton class
# from (irb):10:in `new'
# from (irb):10
# from C:/Ruby193/bin/irb:12:in `<main>'
class Bas < foo_sing ; end
#TypeError: can't make subclass of singleton class
# from (irb):16
# from C:/Ruby193/bin/irb:12:in `<main>'
In the above part I was checking if we can create,instance of singleton class or not and subclass of singleton class,like regular class. But the answers I found as NO. What is the concept or theory or purpose behind it ?
Again in the following code I can see the that same name methods are being overridden inside a singleton class. But when I am searching that method inside the class not found as I asked above.
class Foo ; end
#=> nil
foo = Foo.new
#=> #<Foo:0x225e3a0>
def foo.show ; puts "hi" ; end
#=> nil
foo.show
#hi
#=> nil
class << foo ;def show ; puts "hello" ; end ;end
#=> nil
foo.show
#hello
#=> nil
You're on the right track.
1) When looking for the method in the singleton class, you wanted to use instance_methods, not methods:
foo_sing.instance_methods.include? :bar # => true
# or
foo_sing.method_defined? :bar # => true
It is a bit confusing, since method_defined? really means "instance methods defined?", while methods really means singleton methods...
2) You can't subclass or instantiate a singleton class because it is meant to be a singleton, i.e. have exactly one instance.
It doesn't matter anyways, since you should instead use mixins for code that you want to reuse. These can be included/prepended in as many singleton classes or normal classes as you want:
foo.extend ResuableFunctionality
# or equivalently:
class << foo
include ReusableFunctionality
end
I am writing a class method to create another class method. There seems to be some strangeness around how class_eval and instance_eval operate within the context of a class method. To illustrate:
class Test1
def self.add_foo
self.class_eval do # does what it says on the tin
define_method :foo do
puts "bar"
end
end
end
end
Test1.add_foo # creates new instance method, like I'd expect
Test1.new.foo # => "bar"
class Test2
def self.add_foo
self.instance_eval do # seems to do the same as "class_eval"
define_method :foo do
puts "bar"
end
end
end
end
Test2.add_foo # what is happening here?!
Test2.foo # => NoMethodError
Test2.new.foo # => "bar"
class Test3
def self.add_foo
(class << self; self; end).instance_eval do # call explicitly on metaclass
define_method :foo do
puts "bar"
end
end
end
end
Test3.add_foo # => creates new class method, as I'd expect
Test3.foo # => "bar"
My understanding is that class methods are instance methods defined on the metaclass of the class in question (Test2 in this case). Based on that logic, I would expect the receiver for the class method call add_foo to be the metaclass.
What is self referring to inside the Test2.add_foo method?
Why does calling instance_eval on this receiver object create an instance method?
The main difference between instance_eval and class_eval is that instance_eval works within the context of an instance, while class_eval works within the context of a class. I am not sure how familiar you are with Rails, but let's look at this for an example:
class Test3 < ActiveRecord::Base
end
t = Test3.first
t.class_eval { belongs_to :test_25 } #=> Defines a relationship to test_25 for this instance
t.test_25 #=> Method is defined (but fails because of how belongs_to works)
t2 = Test3.find(2)
t2.test_25 #=> NoMethodError
t.class.class_eval { belongs_to :another_test }
t.another_test #=> returns an instance of another_test (assuming relationship exists)
t2.another_test #=> same as t.another_test
t.class_eval { id } #=> NameError
t.instance_eval { id } #=> returns the id of the instance
t.instance_eval { belongs_to :your_mom } #=> NoMethodError
This happens because belongs_to is actually a method call that happens within the context of the class body, which you cannot call from an instance. When you try to call id with class_eval, it fails because id is a method defined on an instance, not in a class.
Defining methods with both class_eval and instance_eval work essentially the same when called against an instance. They will define a method only on the instance of the object it is called against.
t.class_eval do
def some_method
puts "Hi!"
end
end
t.instance_eval do
def another_method
puts "Hello!"
end
end
t.some_method #=> "Hi!"
t.another_method #=> "Hello!"
t2.some_method #=> NoMethodError
t2.another_method #=> NoMethodError
They differ, however, when dealing with the class.
t.class.class_eval do
def meow
puts "meow!"
end
end
t.class.instance_eval do
def bark
puts "woof!"
end
end
t.meow #=> meow!
t2.meow #=> meow!
t.bark #=> NoMethodError
t2.bark #=> NoMethodError
So where did bark go? It got defined on the instance of the class' singleton class. I'll explain more below. But for now:
t.class.bark #=> woof!
Test3.bark #=> woof!
So to answer your question about what self is referring to within the class body, you can construct a little test:
a = class Test4
def bar
puts "Now, I'm a #{self.inspect}"
end
def self.baz
puts "I'm a #{self.inspect}"
end
class << self
def foo
puts "I'm a #{self.inspect}"
end
def self.huh?
puts "Hmmm? indeed"
end
instance_eval do
define_method :razors do
puts "Sounds painful"
end
end
"But check this out, I'm a #{self.inspect}"
end
end
puts Test4.foo #=> "I'm a Test4"
puts Test4.baz #=> "I'm a Test4"
puts Test4.new.bar #=> Now I'm a #<Test4:0x007fa473358cd8>
puts a #=> But check this out, I'm a #<Class:Test4>
So what is happening here is that in the first puts statement above, we see that inspect is telling us that self within the context of a class method body is referring to the class Test4. In the second puts, we see the same thing, it's just defined differently (using the self.method_name notation for defining class methods). In the third, we see that self refers to an instance of Test4. The last one is a bit interesting because what we see is that self is referring to an instance of Class called Test4. That is because when you define a class, you're creating an object. Everything in Ruby is an object. This instance of object is called the metaclass or the eigenclass or singleton class.
You can access the eigenclass with the class << self idiom. While you're in there, you actually have access to the internals of the eigenclass. You can define instance methods inside of the eigenclass, which is congruent with calling self.method_name. But since you are within the context of the eigenclass, you can attach methods to the eigenclass' eigenclass.
Test4.huh? #=> NoMethodError
Test4.singleton_class.huh? #=> Hmmm? indeed
When you call instance_eval in the context of a method, you're really calling instance_eval on the class itself, which means that you are creating instance methods on Test4. What about where I called instance_eval inside of the eigenclass? It creates a method on the instance of Test4's eigenclass:
Test4.razors #=> Sounds painful
Hopefully, this clears up a few of your questions. I know that I have learned a few things typing out this answer!
Can someone help me make sense of the following? I have the following code in test.rb:
class Dog
end
// bark is declared outside of Dog class
def bark
puts 'Woof!'
end
then in irb:
>> source 'test.rb'
>> a = Dog.new
=> #<Dog:0x117f614>
>> a.bark
Woof!
=> nil
Why does method bark exist in Dog instance even though it is declared outside of the class? Because it's in the same file? Thanks!
When you create a method in the "global" scope (outside of any class), that method is made a private method of Object:
#!/usr/bin/ruby1.8
class Dog
end
p Object.respond_to?(:bark, true) # => false
def bark
puts "Woof!"
end
p Object.respond_to?(:bark, true) # => true
Object is in the ancestry chain of all objects, including Dog:
dog = Dog.new
p dog.class.name # => "Dog"
p dog.class.superclass.name # => "Object"
Therefore dogs (and indeed all objects) now know how to bark. However, the method being private, you'll have to use instance_eval to call it with an explicit receiver:
dog.instance_eval { bark } # => "Woof!"
Or you can call it with an implicit receiver with no gymnastics needed:
bar # => "Woof!"
Your exact example doesn't work in Ruby 1.9. (Apart from the bad comment syntax.)
However, declaring a method in the top level scope will make it a private method on Object, apparently:
>> Object.private_methods.include? :bark
=> true
Perhaps in your Ruby (1.8?), this is a public method?