[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

GOLF (and improve) #instance_interception

Trans

7/14/2006 11:58:00 AM

I have been working on this and was hoping maybe others would like to
take some wacks at it. It's a general purpose tool for prepending a
module in the inheritance chain. Here's an example of it's use. (code
follows):

module A
def f ; "F" ; end
def g ; "G" ; end

instance_interception do
def f( target, *args, &blk )
'{' + target.super + '}'
end
def g( target, *args, &blk )
'{' + target.super + '}'
end
end
end

class X
def f ; super ; end
include A
def g ; super ; end
end

x = X.new
x.f #=> "{F}"
x.g #=> "#{G}"


# instance_interception.rb

class Module

def instance_interception(&block)
@instance_interception ||= Module.new do
def self.append_features(mod)
append_features_without_instance_interception( mod )
end
end
@instance_interception.module_eval(&block) if block_given?
@instance_interception
end

private :instance_interception

alias_method :append_features_without_instance_interception,
:append_features

# Append features

def append_features( mod )

aspect = instance_interception
aspect.__send__( :append_features_without_instance_interception,
mod )

aspect.instance_methods.each do |meth|
if mod.method_defined?( meth )
aspect.advise( mod, meth )
end
end

append_features_without_instance_interception( mod )

#if mod.instance_of? Module
aspect.__send__( :append_features_without_instance_interception,
mod.__send__(:instance_interception) )
#end

end

# Apply the around advice.

def advise( mod, meth )
advice = instance_method( meth )
instance_target = mod.instance_method(meth)
mod.__send__( :define_method, meth ) { |*args| #, &blk|
target = instance_target.bind( self )
(class << target; self; end).class_eval { define_method( :super
){ call( *args ) } }
advice.bind( self ).call( target, *args ) #, &blk )
}
end

# If a method is added to the module/class that is advised.

def method_added( meth )
return if @method_added_short
if instance_interception.method_defined?( meth )
include instance_interception
@method_added_short = true
instance_interception.advise( self, meth )
@method_added_short = false
end
end

end


4 Answers

dblack

7/14/2006 1:04:00 PM

0

Trans

7/14/2006 1:14:00 PM

0


dblack@wobblini.net wrote:
> Hi --
>
> On Fri, 14 Jul 2006, transfire@gmail.com wrote:
>
> > I have been working on this and was hoping maybe others would like to
> > take some wacks at it. It's a general purpose tool for prepending a
> > module in the inheritance chain. Here's an example of it's use. (code
> > follows):
> >
> > module A
> > def f ; "F" ; end
> > def g ; "G" ; end
>
> Well, the golf part is easy, but I don't think it looks very good:
>
> module A;def f;"F";end;def g;"G";end;end
>
> Are you sure you want to golf this? :-)

Well, okay. I guess golf isn't exactly what I mean. Just *improve"
then. Thanks.

BTW, typo in example:

x.g #=> "#{G}"

should be

x.g #=> "{G}"

T.


Ryan Davis

7/15/2006 1:00:00 AM

0

It looks an awful lot like MuffDaddy to me.

http://blog.zenspider.com/archives/2005/02/muffdaddy_...


Trans

7/15/2006 3:23:00 AM

0


Ryan Davis wrote:
> It looks an awful lot like MuffDaddy to me.
>
> http://blog.zenspider.com/archives/2005/02/muffdaddy_...

'Fraid MuffDaddy'z not so "ultimate" -- It's not dynamic.

T.