Asp Forum
Home
|
Login
|
Register
|
Search
Forums
>
comp.lang.ruby
Metaprogramming and module question
Pedro Del Gallego
3/6/2007 9:24:00 PM
Hi
Yesterday , i'd made an example for fun, after read [1]. that let me
introduce pre o post behavior to an method with this easy sintax
class Foo
pre(:my_method) { #some_code}
end
but i ve a proble when i try to move the pre and post method to a
module. Can anyone explainme why the pre methods is undefined in the
class ?
thanks in advance.
[1] :
http://split-s.blogspot.com/2006/02/design-by-contract-for...
My code :
----------------------------------------------------------------------------------------------------------------
Pre and Post method implemented in Song class
class Song
attr_accessor :title
def play
puts "#{@title}"
end
end
class Song
def self.pre (name_method, &condition)
old_method = instance_method(name_method)
define_method(name_method) { |*args|
condition.call
old_method.bind(self).call(*args)
}
end
def self.post (name_method, &condition)
old_method = instance_method(name_method)
define_method(name_method) { |*args|
condition.call
}
end
end
class Song
pre (:play ) { puts "Playing ..." }
end
song = Song.new
song.title= "Hola song"
song.play
----------------------------------------------------------------------------------------------------------------
Als module implementation : not work undefined method `pre' for
Song:Class (NoMethodError)
class Song
attr_accessor :title
def play
puts "#{@title}"
end
end
module MetaTest
def self.included(mod)
puts "and now MetaTest has been used by #{mod.inspect}..."
end
def self.pre (name_method, &condition)
old_method = instance_method(name_method)
define_method(name_method) { |*args|
condition.call
old_method.bind(self).call(*args)
}
end
def self.post (name_method, &condition)
old_method = instance_method(name_method)
define_method(name_method) { |*args|
condition.call
}
end
end
class Song
include MetaTest
end
class Song
pre (:play ) { puts "Playing ..." }
end
song = Song.new
song.title= "Hola caracola"
song.play
--
-------------------------------------
Pedro Del Gallego
Email : pedro.delgallego@gmail.com
3 Answers
Gavin Kistner
3/6/2007 9:33:00 PM
0
On Mar 6, 2:24 pm, "Pedro Del Gallego" <pedro.delgall...@gmail.com>
wrote:
> but i ve a proble when i try to move the pre and post method to a
> module. Can anyone explainme why the pre methods is undefined in the
> class ?
[snip]
Including a Module into a Class only links in the 'instance' methods
of that module as instance methods of the class. Module methods (def
self.foo) are not inherited as 'class' methods.
See
http://phrogz.net/RubyLibs/RubyMethodLook...
for a visual
explanation.
The easiest thing to do is make those methods instance methods of the
module, and extend your Song class with them:
module Foo
def bar; puts "#bar called on #{self}"; end
end
class Cat
include Foo
end
class Dog
extend Foo
end
Cat.bar rescue puts "No Cat.bar method!"
Cat.new.bar rescue puts "No Cat#bar method!"
Dog.bar rescue puts "No Dog.bar method!"
Dog.new.bar rescue puts "No Dog#bar method!"
#=> No Cat.bar method!
#=> #bar called on #<Cat:0x28347b0>
#=> #bar called on Dog
#=> No Dog#bar method!
Pedro Del Gallego
3/6/2007 9:58:00 PM
0
> See
http://phrogz.net/RubyLibs/RubyMethodLook...
for a visual
> explanation.
Good, i think i get it. Good example
--
-------------------------------------
Pedro Del Gallego
Email : pedro.delgallego@gmail.com
Rick DeNatale
3/6/2007 9:59:00 PM
0
On 3/6/07, Phrogz <gavin@refinery.com> wrote:
> On Mar 6, 2:24 pm, "Pedro Del Gallego" <pedro.delgall...@gmail.com>
> wrote:
> > but i ve a proble when i try to move the pre and post method to a
> > module. Can anyone explainme why the pre methods is undefined in the
> > class ?
> [snip]
>
> Including a Module into a Class only links in the 'instance' methods
> of that module as instance methods of the class. Module methods (def
> self.foo) are not inherited as 'class' methods.
>
> See
http://phrogz.net/RubyLibs/RubyMethodLook...
for a visual
> explanation.
>
> The easiest thing to do is make those methods instance methods of the
> module, and extend your Song class with them
And a good way to do this automatically and make including the
MetaTest module do what the OP expects is something like:
module MetaTest
def self.included(mod)
puts "and now MetaTest has been used by #{mod.inspect}..."
mod.extend(ClassMethods)
end
module ClassMethods
def pre (name_method, &condition)
old_method = instance_method(name_method)
define_method(name_method) { |*args|
condition.call
old_method.bind(self).call(*args)
}
end
def post (name_method, &condition)
old_method = instance_method(name_method)
define_method(name_method) { |*args|
condition.call
}
end
end
end
--
Rick DeNatale
My blog on Ruby
http://talklikeaduck.denh...
Servizio di avviso nuovi messaggi
Ricevi direttamente nella tua mail i nuovi messaggi per
Metaprogramming and module question
Inserendo la tua e-mail nella casella sotto, riceverai un avviso tramite posta elettronica ogni volta che il motore di ricerca troverà un nuovo messaggio per te
Il servizio è completamente GRATUITO!
x
Login to ForumsZone
Login with Google
Login with E-Mail & Password