how to wrap method of singleton class

I

Ittay Dror

Hi,


Given a class:

class Foo

class << self

def foo

puts 'foo'

end

end

end


How do I write a module, so that when included in Foo it will wrap the
method foo so that Foo.foo will print:

bar

foo


?


Thank you

Ittay
 
J

James Coglan

[Note: parts of this message were removed to make it a legal post.]
How do I write a module, so that when included in Foo it will wrap the
method foo so that Foo.foo will print:



You can't (at least not without doing some sneaky metaprogramming -- this
code is still a work in progress: http://gist.github.com/25104). A class's
own methods take precedence over any modules mixed into it. What you can do
is reopen the singleton class and store a reference to the old method:

class << Foo # Foo singleton class
old_foo = Foo.method:)foo)
define_method:)foo) do |*args|
old_result = old_foo.call(*args)
old_result.upcase
end
end

Foo.foo #=> "FOO"

You must use define_method for this instead of def. def does not use a block
so you won't get a closure, which you need to retain visibility of the
old_foo variable.
 
I

Ittay Dror

[Note: parts of this message were removed to make it a legal post.]



James said:
You can't (at least not without doing some sneaky metaprogramming -- this
code is still a work in progress: http://gist.github.com/25104). A class's
own methods take precedence over any modules mixed into it. What you can do
is reopen the singleton class and store a reference to the old method:

class << Foo # Foo singleton class
old_foo = Foo.method:)foo)
define_method:)foo) do |*args|
old_result = old_foo.call(*args)
old_result.upcase
end
end
doing it this way, i can do:
class << Foo
alias_method :eek:riginal, :foo
def foo
puts 'bar'
original
end
end

but i want a module i can mix in. (for regular methods, the module can
use the included callback to alias the methods, just not sure how to do
that for a singleton class)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,534
Members
45,007
Latest member
obedient dusk

Latest Threads

Top