[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

How to force a method redefinition ?

Denis Mertz

5/11/2005 8:37:00 PM

Hello,
i'm puzzeld by the following piece of code:

$ cat tests.rb

module B
def xx ; puts "in B" ; end
end
module C
def xx ; puts "in C"; end
end
module D
def xx ; puts "in D"; end
end

include B ; xx
include C ; xx
include D ; xx
include B ; xx
include C ; xx

$ ruby ./tests.rb
in B
in C
in D
in D
in D

I expected
in B
in C
in D
in B
in C

looks like include's are made only once.

Is there another way of getting what i expect ?

thanks

Denis



4 Answers

Robert Klemme

5/11/2005 9:05:00 PM

0


"dm1" <dmertz@online.de> schrieb im Newsbeitrag
news:d5tq7n$sq3$1@online.de...
> Hello,
> i'm puzzeld by the following piece of code:
>
> $ cat tests.rb
>
> module B
> def xx ; puts "in B" ; end
> end
> module C
> def xx ; puts "in C"; end
> end
> module D
> def xx ; puts "in D"; end
> end
>
> include B ; xx
> include C ; xx
> include D ; xx
> include B ; xx
> include C ; xx
>
> $ ruby ./tests.rb
> in B
> in C
> in D
> in D
> in D
>
> I expected
> in B
> in C
> in D
> in B
> in C
>
> looks like include's are made only once.
>
> Is there another way of getting what i expect ?

There are several ways. You can for example fetch methods from a module
with "B.instance_method :xx" and then bind it to an instance. What do you
need that for?

Kind regards

robert

Denis Mertz

5/11/2005 9:27:00 PM

0

Robert Klemme wrote:
>
> There are several ways. You can for example fetch methods from a module
> with "B.instance_method :xx" and then bind it to an instance. What do you
> need that for?

It is for my internationalization project (ri18n). I have two versions of a
set of translator methods, they are contained in modules
Translators::Normal and Translators::Fallback

I'd like to be able to dynamically include one or the other of these modules
into other classes/modules (this works ok with include) and then again
eventually 're-include' the other version (Translators::Fallback -->
Translators::Normal) This does not work with plain old 'include'.

Anyway, i will try with your "B.instance_method :xx" tip

Thanks

Denis

> Kind regards
>
> robert

Christoph R.

5/12/2005 1:35:00 AM

0

Robert Klemme schrieb:

>
> There are several ways. You can for example fetch methods from a
> module with "B.instance_method :xx" and then bind it to an instance.
> What do you need that for?

I guess that would work out
---
module FRedef
def self.extended(mod)
mod.instance_eval do
@instance_methods = Hash.new
instance_methods(false).each do |sym|
@instance_methods[sym] = instance_method(sym)
remove_method(sym)
end
end
end
private
def append_features(mod)
@instance_methods.each do |sym,mth|
mod.__send__(:define_method,sym,mth)
end
super
end
end

module B
def xx ; puts "in B" ; end
extend FRedef
end

module C
def xx ; puts "in C"; end
extend FRedef
end

module D
def xx ; puts "in D"; end
extend FRedef
end


include B ; xx
include C ; xx
include D ; xx
include B ; xx
include C ; xx
---
Note with the -w option you'll get redefinition warnings -
check out singleton.rb on how to avoid this.

/Christoph



Denis Mertz

5/12/2005 9:01:00 AM

0

It works nice. Thanks

Denis

Christoph wrote:

>
> I guess that would work out
> ---
> module FRedef
> def self.extended(mod)
> mod.instance_eval do
> @instance_methods = Hash.new
> instance_methods(false).each do |sym|
> @instance_methods[sym] = instance_method(sym)
> remove_method(sym)
> end
> end
> end
> private
> def append_features(mod)
> @instance_methods.each do |sym,mth|
> mod.__send__(:define_method,sym,mth)
> end
> super
> end
> end
>
> module B
> def xx ; puts "in B" ; end
> extend FRedef
> end
>
> module C
> def xx ; puts "in C"; end
> extend FRedef
> end
>
> module D
> def xx ; puts "in D"; end
> extend FRedef
> end
>
>
> include B ; xx
> include C ; xx
> include D ; xx
> include B ; xx
> include C ; xx
> ---
> Note with the -w option you'll get redefinition warnings -
> check out singleton.rb on how to avoid this.
>
> /Christoph