How to force a method redefinition ?

D

dm1

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
 
R

Robert Klemme

dm1 said:
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
 
D

dm1

Robert said:
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
 
C

Christoph

Robert said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,172
Messages
2,570,933
Members
47,472
Latest member
blackwatermelon

Latest Threads

Top