Is there a practical application to the "crazy-ness" below?
It seems like this is a way for ted
to always be able to return himself to the world and people will think they are talking to ted
who they expect to act a certain way and be a certain age... but he isn't acting the way he portrays himself and is lying about his age to someone.
What 'trickery' is possible when an object is returned and you check on what that object represents and is capable of... but really that object was acting another way and capable of other things before returning.
class Person
def age
21
end
def who_am_i?
puts "I am #{self} / #{object_id} and I am #{age} years old"
self
end
end
ted = Person.new
def ted.singleton_who_am_i?
class << self
def age
0
end
end
puts "I am #{self} / #{object_id} and I am #{age} years old"
self
end
puts ted.who_am_i? == ted.singleton_who_am_i?
>> I am #<Person:0x100138340> / 2148123040 and I am 21 years old
>> I am #<Person:0x100138340> / 2148123040 and I am 0 years old
>> true
http://andrzejonsoftware.blogspot.ca/2011/02/dci-and-rails.html
in DCI, your data model gets different type of behavior based on the context it is used it. Usually it is done with object.extend, but it is pretty much what you are doing above -- taking advantage of the metaclass.
Another example (and probably why things work that way) is the way classes work in ruby. If you say
class Foo
end
that is the same thing as saying
Foo = Class.new
end
meaning that what you are doing is assigning a new instance of class Class to a constant. When you define a method on that class, you don't want it applied to all instance of class Class, you only want it on the class you are defining. So when you say
class Foo
def self.bar
end
end
it is the exact thing as saying
class Foo
end
def Foo.bar
end
which is exactly the same principal as you are talking about in your question
(sorry if that was unclear)