Overridding A Method Via A Mixin

Hi Everyone,

I believe one can add methods to a class by including a module but
not override existing methods. Indeed Dr Nic said as much here:

http://ruby.tie-rack.org/6/safely-overriding-method_missing-in-a-
class-that-already-has-it/#comment-7

Here’s some code that demonstrates this.

class Foo
def answer
42
end
end

module Bar
def answer
“What was the question?”
end

def to_s
“bar”
end
end

Foo.send :include, Bar
f = Foo.new
f.answer # => 42, not “What was the question?”
f.to_s # => “bar”, not “#Foo:0x731248

Why aren’t existing methods overridden? And where could I have
looked to find out the answer for myself (perhaps somewhere in Ruby’s
source?)?

Thanks and regards,
Andy

On 15.01.2008 18:32, Andrew S. wrote:

class Foo
def to_s
Why aren’t existing methods overridden? And where could I have
looked to find out the answer for myself (perhaps somewhere in Ruby’s
source?)?

Because of the position in the inheritance hierarchy:

irb(main):001:0> module Bar;end
=> nil
irb(main):002:0> class Foo
irb(main):003:1> include Bar
irb(main):004:1> end
=> Foo
irb(main):005:0> Foo.ancestors
=> [Foo, Bar, Object, Kernel]

Methods defined in Foo are always found before their counterparts in
included modules. Consequently you can override super class methods
with a module.

Kind regards

robert

On 15 Jan 2008, at 17:40, Robert K. wrote:

Methods defined in Foo are always found before their counterparts
in included modules. Consequently you can override super class
methods with a module.

Aha, of course. Thank you for the clear explanation.

I really should have worked that one out myself!

With regards,
Andy S.

hi andrew!

Andrew S. [2008-01-15 18:32]:

I believe one can add methods to a class by including a module
but not override existing methods.
well, you can override them explicitly:

module Bar
def self.included(base)
methods_to_override = %w[answer]
# or even instance_methods(false)

  methods_to_override.each { |method|
    base.send(:define_method, method, instance_method(method))
  }
end

end

if that’s what you want… :wink:

cheers
jens

On 15.01.2008 19:10, Andrew S. wrote:

=> [Foo, Bar, Object, Kernel]

Methods defined in Foo are always found before their counterparts
in included modules. Consequently you can override super class
methods with a module.

Aha, of course. Thank you for the clear explanation.

You’re welcome!

I really should have worked that one out myself!

Ah, no worries. Once in a while this just happens to all of us.

Btw, you got a nice website there (with a typo on the vortex page g).

Kind regards

robert

Are you a talented Ruby on Rails or mod_perl Developer looking for an
exciting opportunity? My client runs a leading enthusiasts
community/e-commerce site and they need your expertise to create new
features and functions related to social networking. This is a great
opportunity to work with a fun group and contribute to exciting
technology that’s used by many!

Qualifications:

  • Thorough understanding of object-oriented methodology
  • Thorough understanding of MVC architectures
  • Experience with coding database-backed web applications
  • Expert knowledge in either mod_perl or Ruby on Rails
  • Intermediate knowledge of a mod_perl templating language
  • Intermediate CSS and Javascript skills
  • Willingness to work in an Agile development environment
  • Ability to clearly and concisely communicate technical ideas

If you are interested or know someone that is interested please have
them email a resume as a Word attachment to [email protected] or
[email protected]

Thanks!
Scot Baker
Technical Recruiting Manager
parker technical
605 Fifth Avenue South -Suite 850- Seattle, WA 98104
[email protected] | p: 206-652-1587 | f: 206-223-8227 |
c:206-915-9020
http://www.linkedin.com/in/scotbaker

Where is this at? This is one of the most vague job listings I’ve ever
seen.

I’m assuming Seattle?

–Jeremy

On Jan 15, 2008 1:29 PM, Scot H. Baker [email protected]
wrote:


http://www.jeremymcanally.com/

My books:
Ruby in Practice

My free Ruby e-book

My blogs:

http://www.rubyinpractice.com/

As long as it’s close to a Soup Kitchen they have the free lunch thing
covered.

On Jan 15, 2008 12:19 PM, Jeremy McAnally [email protected]
wrote:

exciting opportunity? My client runs a leading enthusiasts

  • Expert knowledge in either mod_perl or Ruby on Rails
    Scot Baker

http://www.humblelittlerubybook.com/

My blogs:
http://www.mrneighborly.com/
http://www.rubyinpractice.com/


“Hey brother Christian with your high and mighty errand, Your actions
speak
so loud, I can’t hear a word you’re saying.”

-Greg Graffin (Bad Religion)

On Jan 15, 2008 8:33 PM, ara.t.howard [email protected] wrote:

this allows you to both override and super up, in any combination,
with a method injected late into a class hierarchy
Actually whenever these issues come up I wonder why we still define
methods in classes?
Either, using pure Ruby implementening all functionality im Modules
(with the dangerous pitfall of double inclusion, or just using Traits
Composition would just end all of that kind of complexity) But even I
do not use my Traits package, old habits are difficult to lose
indeed…
Cheers
Robert

http://ruby-smalltalk.blogspot.com/


Whereof one cannot speak, thereof one must be silent.
Ludwig Wittgenstein

On Jan 15, 2008, at 10:32 AM, Andrew S. wrote:

Hi Everyone,

I believe one can add methods to a class by including a module but
not override existing methods. Indeed Dr Nic said as much here:

http://ruby.tie-rack.org/6/safely-overriding-method_missing-in-a-
class-that-already-has-it/#comment-7

i personally avoid aliases like that - they stack when you double
require or double include a module and throw into a loop. this kind
of thing can be done safely and generically using a variable for the
previous method that’s protected from the gc and a lookup in the new
method:

cfp:~ > cat a.rb
class A
def foo
p “A.foo”
end
end
class B
end

module M
NoGC = []

def self.included other
other.module_eval do
if((foo = instance_method ‘foo’ rescue false))
NoGC.push foo
supra = “ObjectSpace._id2ref(#{ foo.object_id }).bind
(self).call(*a, &b)”
end
eval <<-code
def foo *a, &b
#{ supra }
p “M.foo”
end
code
end
end
end

A.send :include, M
B.send :include, M

A.new.foo
B.new.foo

cfp:~ > ruby a.rb
“A.foo”
“M.foo”
“M.foo”

this allows you to both override and super up, in any combination,
with a method injected late into a class hierarchy

kind regards

a @ http://codeforpeople.com/

On 15 Jan 2008, at 18:39, Robert K. wrote:

Btw, you got a nice website there (with a typo on the vortex page
g).

Thanks! You are kind to say so.

I can’t find that typo though…are you pulling my leg? :slight_smile:

With regards,
Andy S.

On 15 Jan 2008, at 19:33, ara.t.howard wrote:

i personally avoid aliases like that - they stack when you double
require or double include a module and throw into a loop. this
kind of thing can be done safely and generically using a variable
for the previous method that’s protected from the gc and a lookup
in the new method:

I see. That sounds much more sensible.

NoGC = []
#{ supra }
A.new.foo
with a method injected late into a class hierarchy
Wonderful!

I should confess that I haven’t entirely convinced myself that I
understand your construction of supra. Given that you have the
unbound method in the foo variable, is the reason why you can’t bind
foo directly, perhaps like this:

 supra = "#{foo}.bind(self).call(*a, &b)"

…because there’s no way to write the string so it eval’s the way we
want it to?

Thank you for the enlightenment :slight_smile:

Regards,
Andy S.

On Jan 16, 2008 10:06 AM, Andrew S. [email protected]
wrote:

On 15 Jan 2008, at 18:39, Robert K. wrote:

Btw, you got a nice website there (with a typo on the vortex page
g).

Thanks! You are kind to say so.

I can’t find that typo though…are you pulling my leg? :slight_smile:

I think he was joking since Americans typically use “specialize” and
“center” instead :slight_smile:

Todd

On 16.01.2008 19:19, Todd B. wrote:

On Jan 16, 2008 10:06 AM, Andrew S. [email protected] wrote:

On 15 Jan 2008, at 18:39, Robert K. wrote:

Btw, you got a nice website there (with a typo on the vortex page
g).
Thanks! You are kind to say so.

You’re welcome! I really like the clean design. You know, I am more
the “Braun” type than the “Hundertwasser” type. Also, I noticed you use
Mongrel for hosting. :slight_smile:

I can’t find that typo though…are you pulling my leg? :slight_smile:

I think he was joking since Americans typically use “specialize” and
“center” instead :slight_smile:

Nope. First, I am not American* and second, these are not the words I
had in mind. The “offending” word is somewhere between “organised” and
“David Allen’s”. To give an additional hint, it’s spelled correct and
wrong in the same paragraph. :slight_smile:

Cheers

robert

  • Although I have to say that most English I am exposed to is probably
    American English. :slight_smile:

On 15 Jan 2008, at 18:15, Jens W. wrote:

end

end

if that’s what you want… :wink:

There’s always a way! Thanks Jens, that’s neat.

Regards,
Andy S.

On 16 Jan 2008, at 19:39, Robert K. wrote:

The “offending” word is somewhere between “organised” and “David
Allen’s”. To give an additional hint, it’s spelled correct and
wrong in the same paragraph. :slight_smile:

Got it. Quelle gaffe!

I like to take pride in shunning automatic spell-checking…so I
shouldn’t be surprised when a fall follows :slight_smile:

Kind regards,
Andy S.

On Jan 16, 2008 1:39 PM, Robert K. [email protected]
wrote:

Nope. First, I am not American* and second, these are not the words I
had in mind.

Got it. Easy to miss. Also, I assumed you were talking about the home
page.

cheers,
Todd