ivan
ivan

Reputation: 6322

Ruby: using a hash to access instance methods

I'm working on a problem in Chris Pine's Learn to Program book. I've defined a class Pet, with some instance methods. Outside of the class definition, I'm trying to build a method that will take a string and an instance of the Pet class and run the appropriate instance method.

def dispatch(command, pet)
  dispatches = {'feed'       => pet.feed,
                'walk'       => pet.walk,
                'put to bed' => pet.putToBed,
                'rock'       => pet.rock,
                'toss'       => pet.toss}
  dispatches[command]
end

When the dispatch method runs, however, it executes all the instance methods that appear in the hash, not just the one corresponding to command. They execute in the order they appear in the code, and before even reaching the dispatches[command] line.

What am I doing wrong here?

Upvotes: 1

Views: 275

Answers (2)

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230326

Yes, that is correct behaviour.

{'feed'       => pet.feed}

The line above means "call method pet.feed and use its return value for assigning to key 'feed'". You have to use lambdas (or similar) to create chunks of code that can be invoked later. Something like this:

def dispatch(command, pet)
  dispatches = {'feed'       => proc { pet.feed },
                'put to bed' => proc { pet.put_to_bed }}
  dispatches[command].call
end

Upvotes: 3

spickermann
spickermann

Reputation: 106812

While creation of the hash all methods are evaluated. I advise to read about the use of the method send (http://www.ruby-doc.org/core-2.0.0/Object.html#method-i-send) If you use send you will end with something like:

def dispatch(command, pet)
  pet.send(command)
end

Note that you will need to adjust the name of the method putToBed.

Upvotes: 1

Related Questions