Announcement (2017-05-07): www.ruby-forum.com is now read-only since I
unfortunately do not have the time to support and maintain the forum any
more. Please see rubyonrails.org/community and ruby-lang.org/en/community
for other Rails- und Ruby-related community platforms.

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

> 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.

James Coglan wrote:
>> 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 :original, :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)
> 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.>>
--
Ittay Dror <ittayd@tikalk.com>
Tikal <http://www.tikalk.com>
Tikal Project <http://tikal.sourceforge.net>