Stefano Crocco
8/28/2008 8:23:00 PM
On Thursday 28 August 2008, Stefano Crocco wrote:
> On Thursday 28 August 2008, Chris Bailey wrote:
> > I'm trying to come up with an efficient way of using user input as a
> > way of calling methods. I'm unhappy with the way that I am doing it
> > because it isn't very flexible. This is what I'm doing now.
> >
> > input = gets.downcase.chomp
> >
> > if input == foo
> > do_foo()
> > elsif input == bar
> > do_bar()
> > else
> > puts "That isn't a command!"
> > end
> >
> > What I would like to do is more like so.
> >
> > commands = {
> > 'foo' => do_foo(),
> > 'bar' => do_bar()
> > }
> >
> > I then would like to search the commands hash for a key that matches the
> > player input and execute the method associated with that key. What I've
> > noticed is that upon initialization of the hash the value becomes equal
> > to the result of the method but that is not what I want. If I store the
> > value as a string ie "do_foo()" would I be able to parse that string and
> > execute it as a method? And if so, how would that be done?
>
> You can do something like this:
>
> method_name = gets.downcase.chomp
> send method_name
>
> send is a method which takes as a first argument a method name (as a string
> or symbol) and calls that method on its receiver, passing all the remaining
> arguments to it (see ri Object#send for a better explaination). To better
> handle the possibility the user inserts a wrong string, you can rescue the
> NoMethodError exception:
>
> method_name = gets.downcase.chomp
> begin
> send method_name
> rescue NoMethodError
> puts "#{method_name} is not a valid command"
> end
>
> If you want to restrict the methods the user can call, store them in an
> array and check whether the string he entered is there before calling send:
>
> commands = %w[foo bar]
> method_name = gets.downcase.chomp
> if commands.include? method_name then send method_name
> else puts "#{method_name} is not a valid command"
> end
>
> I hope this helps
>
> Stefano
Of course, with this approach, you'll need to change the names of your methods
to foo and bar, or to change the definition of method_name to something like
this:
method_name = "do_#{gets.downcase.chomp}"
Stefano