being reading some codes of self used in ruby, still can not figure out some examples:
class A
def hi
"hi"
end
def self.hello
"hello"
end
end
a=A.new
a.hi
A.hello
understand I can use below to change instance method def:
class << a
def hi
"hi from a <<"
end
end
a.hi => "hi from a <<"
but what is this?
class << a
def self.hello
"H E L L O"
end
end
[21] pry(main)> A.hello
=> "hello"
[22] pry(main)> a.hello
<<ERROR1>> NoMethodError: undefined method `hello' for #<A:0x007fe41338ecb8>
and I am not really sure what I am doing here actually.
and what is difference between the definition
class << a
def hi
"hi from a <<"
end
end
and
class << A
def hi
"hi from a <<"
end
end
?
----------------------question added a little further----------------------
class A
p "in class A: #{self}, type: #{self.class}"
def f
p "in f: #{self}, type: #{self.class}"
end
def self.m
p "in selfm: #{self}, type: #{self.class}"
end
end
metaclass = class << a;self;end
metaclass.instance_eval do
"hi : #{self}, type: #{self.class}"
def f7
"in f7 .. : #{self}, type: #{self.class}"
end
def self.f9
"in f7 .. : #{self}, type: #{self.class}"
end
end
A.f7
a.f7
A.f9
a.f9
<<ERROR2>>
[20] pry(main)> A.f9
NoMethodError: undefined method f9' for A:Class
from (pry):40:in
pry'
[21] pry(main)> a.f9
NoMethodError: undefined method f9' for #<A:0x007fb70717c0d0>
from (pry):41:in
pry'
<<ERROR3>>
[22] pry(main)>
[23] pry(main)> A.f7
NoMethodError: undefined method f7' for A:Class
from (pry):42:in
pry'
[24] pry(main)> a.f7
NoMethodError: undefined method f7' for #<A:0x007fb70717c0d0>
from (pry):43:in
pry'
[25] pry(main)> A.f9
NoMethodError: undefined method f9' for A:Class
from (pry):44:in
pry'
[26] pry(main)> a.f9
NoMethodError: undefined method f9' for #<A:0x007fb70717c0d0>
from (pry):45:in
pry'
Can you help pin point what exactly these errors are: refer to <> mark
- see that the <>, my question:
Does it make any sense to define self.method in an object, if not, why there is no warring/error? if it make sense, what does it mean for a self.method for an object?
>, why f7 is not callable using both A's class and object?
>, why f9 is not callable using both A's class and object?
A little more for discussion:
<>
class A
def self.f1
"f1"
end
def self.f2(&block)
(class << self; self; end).instance_eval do
define_method("f1", &block)
end
end
def self.f3(&block)
m=(class << self; self; end)
m.instance_eval do
define_method("f1", &block)
end
end
def self.f4(&block)
m=(class << self; self; end)
m.instance_eval do
def f1
"f4 is called"
end
end
end
def self.f5(&block)
m=(class << self; self; end)
m.instance_eval do
def f1
"f5 is called"
end
end
end
end
Seems I am little closer to the truth now, here's final one need to get the magic revealed:
If I do
A.f2 do
"f2 is called"
end
A.f1
A.f3 do
"f3 is called"
end
A.f1
I am able to overwrite the f1 method with either A.f2 or A.f3 call, however if I directly def method in instance_eval block, it won't achieve the same goal, what's the difference here?
A.f4
A.f1
A.f5
A.f1
the A.f1 still returns "f1". What I found is that if you use the def, then the method is defined and tied with eigen class instance, if you use define_method, the method then is tied with class A as static method.
What's the difference here between the usage of define_method and def ?