From: Sean O'Halpin Date: 2007-10-20T07:38:55+09:00 Subject: Re: Puzzle...cleaner way to redefine a method? ------=_Part_5373_28447203.1192833535196 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 7bit Content-Disposition: inline Hi, maybe this is slightly cleaner in interface (in that you pass in pre and post procs rather than a string) but you still need to use eval somewhere (in Ruby 1.8 anyway) to be able to use 'def' so you can pass on the block. Shows the principle anyway. module Wrapper def wrap(meth, pre_block, post_block) m = Module.new do define_method "pre_#{meth}", &pre_block define_method "post_#{meth}", &post_block eval %[ def #{meth}(*a, &b) pre_#{meth} rv = super(*a, &b) post_#{meth} rv end ] end self.extend m end end class Thing include Wrapper def working yield end def main working do p 'test' end end end a = Thing.new a.main a.wrap :working, proc { p 'pre' }, proc { p 'post' } a.main __END__ "test" "pre" "test" "post" If you don't want to include Wrapper in the class, you could use a.extend(Wrapper) instead. Regards, Sean On 10/19/07, Blackie wrote: > > Here's a puzzle. There must be a cleaner way to do this. > > I would like to have users of this class be able to call "set_wrapper" > and define pre and post behavior on the "working" method. The only > simple way I've found is evaling a string the redefines "working". > Searching threads on instance and class_eval tends to turn up an oil > slick of arguments and misinformation. Help is apprecaited! > > ~~~~~~~~~~ > class Thing > def set_wrapper(string) > eval(string) > end > > def working > yield > end > > def main > working do > p 'test' > end > end > end > > a = Thing.new > > a.main > > a.set_wrapper("def working; p 'pre'; yield; p 'post'; end") > > a.main > > > ------=_Part_5373_28447203.1192833535196--