# Switching dynamically between methods (inside modules)

**URL:** <https://www.ruby-forum.com/t/switching-dynamically-between-methods-inside-modules/187850>\
**Category:** Ruby\
**Created:** [April 30, 2010, 12:50pm UTC](https://www.ruby-forum.com/t/switching-dynamically-between-methods-inside-modules/187850 "2010-04-30T12:50:04Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![judge](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@judge](https://www.ruby-forum.com/u/judge)\
**Post date:** [April 30, 2010, 12:50pm UTC](https://www.ruby-forum.com/t/switching-dynamically-between-methods-inside-modules/187850/1 "2010-04-30T12:50:04Z")

</div>

Hi,

I would like to allow a person object (instanced from a Person class) to  
speak a language (which is a collection of public methods stored in  
Language module):

> > class Person  
> > attr\_accessor :current\_language
> > 
> > def quit  
> > # Unselect the current language, if any:  
> > @current\_language = nil  
> > end  
> > end

Suppose that languages are the following:

> > module Language  
> > module Japanese  
> > def konnichiwa  
> > “ã“ã‚“ã«ã¡ã¯ï¼ (in #{@current\_language} language)”  
> > end
> > 
> > ```
> > def sayounara
> > "ã•ã‚ˆã†ãªã‚‰ã€‚ (in #{@current_language} language)"
> > end
> > 
> > ```
> > 
> > end
> > 
> > module French  
> > def bonjour  
> > “Bonjour ! (in #{@current\_language} language)”  
> > end
> > 
> > ```
> > def au_revoir
> > "Au revoir. (in #{@current_language} language)"
> > end
> > 
> > ```
> > 
> > end
> > 
> > module English  
> > def hello  
> > “Hello! (in #{@current\_language} language)”  
> > end
> > 
> > ```
> > def bye
> > "Bye. (in #{@current_language} language)"
> > end
> > 
> > ```
> > 
> > end  
> > end

Example of use:

person = Person.new

person.current\_language # =\> nil  
person.hello # =\> may raise a nice no method error

person.current\_language = :english  
person.hello # =\> “Hello! (from english instance variable)”  
person.bonjour # =\> may also raise a no method error  
person.quit

person.current\_language = :french  
person.bonjour # =\> “Bonjour ! (from french instance variable)”

As you can see, a language is such as a protocol. So a person can switch  
on a specific protocol, but only one at a time.

For modular reasons, storing each language into a module is friendly. So  
I think this way is the more logical Ruby way, isn’t it.

So I would like to merge and unmerge dynamically module’s methods (with  
a kind of dynamic include) into the object… and then (for instance)  
access them with person.public\_send(). Thus, instance variables like  
@current\_language are still accessible from the new methods.

But, I believe that it is not possible to write something like this:

> > class Person
> > 
> > # wrong code:
> > 
> > include “Language::#{@current\_language}” unless @current\_language.nil?  
> > end

According to you, what could be the best practice to do so?

Any comments and messages are welcome. Thank you.

Regards

---

<div class="post-metadata">

**Author:** ![judge](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@judge](https://www.ruby-forum.com/u/judge)\
**Post date:** [April 30, 2010, 1:27pm UTC](https://www.ruby-forum.com/t/switching-dynamically-between-methods-inside-modules/187850/2 "2010-04-30T13:27:50Z")

</div>

On Fri, Apr 30, 2010 at 12:50 PM, Paul A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:  
A first, elegant approach suffers from the minor defect that it does not  
work ;(  
module A  
def a; “A” end  
end

module B  
def a; “B” end  
end

o = Object::new  
o.extend A  
puts o.a  
o.extend B  
puts o.a  
o.extend A  
puts o.a

thus more work is needed  
the following code will give you some ideas, I hope

class Module  
def apply obj  
this\_mod = self  
methods = instance\_methods( false ).map{ | mname | [ mname,  
instance\_method( mname ) ] }  
p methods  
class \<\< obj; self end.module\_eval do  
include this\_mod  
methods.each do | name, mthd |  
define\_method name do | \*args, &blk |  
mthd.bind( self ).call( \*args, &blk )  
end  
end  
end  
end  
end  
module A  
def a; “A” end  
end

module B  
def a; “B” end  
end

class Object  
def force\_extend \*mods  
mods.each do | mod |  
mod.apply self  
end  
end  
end  
o = Object::new  
o.force\_extend A  
puts o.a  
o.force\_extend B  
puts o.a  
o.force\_extend A  
puts o.a

HTH  
R.

---

<div class="post-metadata">

**Author:** ![judge](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@judge](https://www.ruby-forum.com/u/judge)\
**Post date:** [April 30, 2010, 1:34pm UTC](https://www.ruby-forum.com/t/switching-dynamically-between-methods-inside-modules/187850/3 "2010-04-30T13:34:16Z")

</div>

Oh BTW, traits do exactly what you want, maybe you want to check out  
my implementation  
[http://rubyforge.org/frs/?group\_id=4642](http://rubyforge.org/frs/?group_id=4642)

might save you some troubles.  
R.

---

<div class="post-metadata">

**Author:** ![judge](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@judge](https://www.ruby-forum.com/u/judge)\
**Post date:** [April 30, 2010, 3:00pm UTC](https://www.ruby-forum.com/t/switching-dynamically-between-methods-inside-modules/187850/4 "2010-04-30T15:00:54Z")

</div>

2010/4/30 Rick DeNatale [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> To me, this problem cries out for delegation rather than inheritance  
> or module inclusion.

Absolutely!

> Here’s a first cut.

Reminds me of a bad record by a famous band which had otherwise really  
great stuff - back in 60s to 80s… 🙂

> This also has the advantage that it can fairly easily be extended to  
> support multilingual people. Something even a few of us Americans  
> think is une bonne idée!

🙂

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![judge](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@judge](https://www.ruby-forum.com/u/judge)\
**Post date:** [April 30, 2010, 2:30pm UTC](https://www.ruby-forum.com/t/switching-dynamically-between-methods-inside-modules/187850/5 "2010-04-30T14:30:27Z")

</div>

To me, this problem cries out for delegation rather than inheritance  
or module inclusion.

Here’s a first cut.

module Language

Japanese = {  
:konnichiwa =\> “ã“ã‚“ã«ã¡ã¯ï¼ (in Japanese language)”,  
:sayounara =\> “ã•ã‚ˆã†ãªã‚‰ã€‚ (in Japanese language)”  
}

French = {  
:bonjour =\> “Bonjour ! (in French language)”,  
:au\_revoir =\> “Au revoir. (in French language)”  
}

English = {  
:hello =\>“Hello! (in English language)”,  
:bye =\> “Bye. (in English language)”  
}

class NewBornKnowledge  
def self.method\_missing(word, \*args)  
“Goo Goo Gaa Gaa (in BabyTalk)”  
end

```
def to_s
  nil
end

```

end

class Knowledge

```
def initialize(language)
  @language = language
  @dictionary = Language.const_get(language.to_sym)
end

def to_s
  @language
end

def method_missing(word, *args)
  @dictionary[word] || "that's not a word in #{@language}"
end

```

end

def self.knowledge\_for(language=nil)  
if language  
Knowledge.new(language)  
else  
NewBornKnowledge  
end  
end

end

class Person  
def initialize(language = nil)  
self.current\_language = language  
end

def method\_missing(word, \*args)  
@language\_center.send(word)  
end

def current\_language=(language)  
@language\_center = Language.knowledge\_for(language)  
end

def quit  
self.current\_language = nil  
end  
end

person = Person.new

person.current\_language # =\> “Goo Goo Gaa Gaa (in BabyTalk)”  
person.hello # =\> “Goo Goo Gaa Gaa (in BabyTalk)”

person.current\_language = :English  
person.hello # =\> “Hello! (in English language)”  
person.bonjour # =\> “that’s not a word in English”  
person.quit

person.hello # =\> “Goo Goo Gaa Gaa (in BabyTalk)”  
person.bonjour # =\> “Goo Goo Gaa Gaa (in BabyTalk)”  
person.konnichiwa # =\> “Goo Goo Gaa Gaa (in BabyTalk)”

person.current\_language = :French  
person.bonjour # =\> “Bonjour ! (in French language)”

This also has the advantage that it can fairly easily be extended to  
support multilingual people. Something even a few of us Americans  
think is une bonne idÃ©e!

–  
Rick DeNatale

Blog: [http://talklikeaduck.denhaven2.com/](http://talklikeaduck.denhaven2.com/)  
Github: [rubyredrick (Rick DeNatale) · GitHub](http://github.com/rubyredrick)  
Twitter: @RickDeNatale  
WWR: [http://www.workingwithrails.com/person/9021-rick-denatale](http://www.workingwithrails.com/person/9021-rick-denatale)  
LinkedIn: [http://www.linkedin.com/in/rickdenatale](http://www.linkedin.com/in/rickdenatale)

---

<div class="post-metadata">

**Author:** ![judge](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@judge](https://www.ruby-forum.com/u/judge)\
**Post date:** [April 30, 2010, 3:32pm UTC](https://www.ruby-forum.com/t/switching-dynamically-between-methods-inside-modules/187850/6 "2010-04-30T15:32:56Z")

</div>

Impressive code, thanks Rick Denatale! Thank you too, Robert D.! I  
am currently reading your solutions.

Anyway, I don’t know if delegation is the best option for my needs.  
Actually, if for instance we update Person class such as:

class Person  
attr\_accessor :name

def initialize(language = nil)  
self.current\_language = language  
end

def method\_missing(word, \*args)  
@language\_center.send(word)  
end

def current\_language=(language)  
@language\_center = Language.knowledge\_for(language)  
end

def quit  
self.current\_language = nil  
end  
end

…and English hash like this:

module Language  
English = {  
:hello =\> “Hello! My name is #{@name}.”,  
:bye =\> “Bye. (in English language)”  
}

# …

}

…then it’s hard to access instance variables (and instance methods)  
from person object:

person = Person.new  
person.name = “Paul”

person.current\_language = :English  
person.hello # =\> “Hello! My name is .”

Maybe only inheritance can do it, no? It’s tricky :s

Best regards.  
P.

---

<div class="post-metadata">

**Author:** ![judge](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@judge](https://www.ruby-forum.com/u/judge)\
**Post date:** [April 30, 2010, 3:21pm UTC](https://www.ruby-forum.com/t/switching-dynamically-between-methods-inside-modules/187850/7 "2010-04-30T15:21:24Z")

</div>

On Fri, Apr 30, 2010 at 2:57 PM, Robert K.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 2010/4/30 Rick DeNatale [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):
> 
> > To me, this problem cries out for delegation rather than inheritance  
> > or module inclusion.
> 
> Absolutely!  
> Ok can you kinda stop of spoiling the fun ;).

I really did not analyze the use case. Delegation is often forgotten  
and often could be used instead of inheritance with beneficial  
effects.  
However, traits are behavior based on, well traits and _not_  
inheritance.  
I believe that traits are not really used anywhere in the spirit of  
the “original”. If I am mistaken that would be a joyful surprise. And  
it would allow us to better study traits vs. x. In our case x being  
delegation.

The question I would like to see answered is: Is it really the  
responsibility of a delegate to do the work? Look at where the data  
lives. In our case delegation is wonderful as there is an almost  
perfect decoupling of the language data. When the delegate needs many  
features of the delegator(sp?) however, traits become a really good  
alternative.  
And sorry for the advertising 😉

> 

Cheers  
R.

---

<div class="post-metadata">

**Author:** ![judge](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@judge](https://www.ruby-forum.com/u/judge)\
**Post date:** [April 30, 2010, 3:43pm UTC](https://www.ruby-forum.com/t/switching-dynamically-between-methods-inside-modules/187850/8 "2010-04-30T15:43:38Z")

</div>

2010/4/30 Paul A. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> self.current\_language = language  
> def quit  
> self.current\_language = nil  
> end  
> end
> 
> …and English hash like this:
> 
> module Language  
> English = {  
> :hello =\> “Hello! My name is #{@name}.”,

This does not work as the #{} is expanded right here, i.e. if you look  
at the map you’ll likely find this:  
“Hello! My name is .”

> person.current\_language = :English  
> person.hello # =\> “Hello! My name is .”
> 
> Maybe only inheritance can do it, no? It’s tricky :s

No, you just need to change the contract between Person and the  
delegate. You can for example pass on self (i.e. the Person instance)  
and the delegate extracts instance variable values via  
instance\_variable\_get. You can also do it the other way round and  
make delegate methods expect an object which replies to particular  
methods (like a callback interface in other languages).

Inheritance is often abused IMHO. People seem to tend to lump too  
much disparate functionality together in a single inheritance  
hierarchy. At least that’s my observation.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![judge](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/9de0a6/32.png) [@judge](https://www.ruby-forum.com/u/judge)\
**Post date:** [April 30, 2010, 3:46pm UTC](https://www.ruby-forum.com/t/switching-dynamically-between-methods-inside-modules/187850/9 "2010-04-30T15:46:34Z")

</div>

2010/4/30 Robert D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

> On Fri, Apr 30, 2010 at 2:57 PM, Robert K.  
> [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:
> 
> > 2010/4/30 Rick DeNatale [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):
> > 
> > > To me, this problem cries out for delegation rather than inheritance  
> > > or module inclusion.
> > 
> > Absolutely!  
> > Ok can you kinda stop of spoiling the fun ;).

How can I stop you from having fun? It’s a free world and you can do  
whatever pleases you.

> I really did not analyze the use case. Delegation is often forgotten  
> and often could be used instead of inheritance with beneficial  
> effects.

Exactly Rick’s and my point.

> However, traits are behavior based on, well traits and _not_ inheritance.  
> I believe that traits are not really used anywhere in the spirit of  
> the “original”. If I am mistaken that would be a joyful surprise. And  
> it would allow us to better study traits vs. x. In our case x being  
> delegation.

I would look a bit further into this if I had enough time right now.  
I have to admit I don’t really have a firm grip on traits so I would  
have to do some research upfront to be able to properly comment on  
that matter.

> The question I would like to see answered is: Is it really the  
> responsibility of a delegate to do the work? Look at where the data  
> lives. In our case delegation is wonderful as there is an almost  
> perfect decoupling of the language data. When the delegate needs many  
> features of the delegator(sp?) however, traits become a really good  
> alternative.  
> And sorry for the advertising 😉

No sweat.

Kind regards

robert
