This surprised me:
module English; def say; "yes"; end; end
module French; def say; "oui"; end; end
x = Object.new
x.extend English
x.say # "yes"
x.extend French
x.say # "oui"
x.extend English
x.say # "oui"
What wrong assumptions am I making that this surprises me? What is
the more elegant "Ruby way" of alternating an object's behavior at
runtime?
Thanks,
Jim
Jim Crossley:
This surprised me:
module English; def say; "yes"; end; end
module French; def say; "oui"; end; end
x = Object.new
x.extend English
This adds English to the front of the method look-up path.
x.say # "yes"
At this point, the #say method is first looked-up in English.
x.extend French
This adds French to the front of the method look-up path.
x.say # "oui"
At this point, the #say method is first looked-up in French.
x.extend English
Hey, English is already in the method look-up path, no need to add it!
x.say # "oui"
Oui, French is still at the front of the method look-up path…
What wrong assumptions am I making that this surprises me?
That the second #extend call moved English
to the front of the method look-up path.
What is the more elegant "Ruby way" of
alternating an object's behavior at runtime?
I don’t have hand-on experience, and there probably is a simple,
canonical way, but I’d start with looking at Object#instance_eval.
— Shot
···
--
Anyone who finds the MS Office ribbon intuitive is
not a member of the human species as I understand it.
[William Morgan]
This surprised me:
module English; def say; "yes"; end; end
module French; def say; "oui"; end; end
x = Object.new
x.extend English
x.say # "yes"
x.extend French
x.say # "oui"
x.extend English
x.say # "oui"
What wrong assumptions am I making that this surprises me?
Matz has already explained that module inclusion is a one-time only deal.
Here's a bit on why that is.
http://talklikeaduck.denhaven2.com/2007/11/03/a-chat-with-matz-classs-variable-reversion-and-a-mystery-explained
What is
the more elegant "Ruby way" of alternating an object's behavior at
runtime?
I'd use a form of delegation
module English; def self.agree; "yes"; end; end
module French; def self.agree; "oui"; end; end
class Speaker
attr_accessor :language
def initialize(language = English)
self.language = language
end
def say
language.agree
end
def speak(language)
self.language = language
end
end
jack = Speaker.new
jacques = Speaker.new(French)
jack.say # => "yes"
jacques.say # => "oui"
jack.speak(French)
jacques.speak(English)
jack.say # => "oui"
jacques.say # => "yes"
jack.speak(English)
jacques.speak(French)
jack.say # => "yes"
jacques.say # => "oui"
···
On Sat, Nov 14, 2009 at 9:50 AM, Jim Crossley <jim@crossleys.org> wrote:
--
Rick DeNatale
Blog: http://talklikeaduck.denhaven2.com/
Twitter: http://twitter.com/RickDeNatale
WWR: http://www.workingwithrails.com/person/9021-rick-denatale
LinkedIn: http://www.linkedin.com/in/rickdenatale