Arguments into method calls?

T

Torrey Slattery

I'm working on a program that takes user input via command line, then
calls whatever method is related to that input text.

For instance, if they type /help it calls the method help, if they type
/quit it calls the method quit, /time calls time, etc.

Essentially, if they type in something with a slash, I want the program
to interpret it as a special command, strip off the / and calls a method
with the leftover text.

I can think of a clunky way to do this using a ton of if/elsif clauses
and matching regular expressions, but as I eventually plan to have over
a hundred commands, that doesn't seem pleasant to write at all.

Is there a cleaner way to do this?
 
T

Tim Hunter

Torrey said:
I'm working on a program that takes user input via command line, then
calls whatever method is related to that input text.

For instance, if they type /help it calls the method help, if they type
/quit it calls the method quit, /time calls time, etc.

Essentially, if they type in something with a slash, I want the program
to interpret it as a special command, strip off the / and calls a method
with the leftover text.

I can think of a clunky way to do this using a ton of if/elsif clauses
and matching regular expressions, but as I eventually plan to have over
a hundred commands, that doesn't seem pleasant to write at all.

Is there a cleaner way to do this?
Check out the __send__ method, which lets you call a method whose name
is in a variable:

obj.__send__(method_name, args)
 
V

vasudevram

Torrey said:
I'm working on a program that takes user input via command line, then
calls whatever method is related to that input text.
For instance, if they type /help it calls the method help, if they type
/quit it calls the method quit, /time calls time, etc.
Essentially, if they type in something with a slash, I want the program
to interpret it as a special command, strip off the / and calls a method
with the leftover text.
I can think of a clunky way to do this using a ton of if/elsif clauses
and matching regular expressions, but as I eventually plan to have over
a hundred commands, that doesn't seem pleasant to write at all.
Is there a cleaner way to do this?

Check out the __send__ method, which lets you call a method whose name
is in a variable:

obj.__send__(method_name, args)

--
RMagick OS X Installer [http://rubyforge.org/projects/rmagick/]
RMagick Hints & Tips [http://rubyforge.org/forum/forum.php?forum_id=1618]
RMagick Installation FAQ [http://rmagick.rubyforge.org/install-faq.html]- Hide quoted text -

- Show quoted text -

Tim Hunter is right. Just adding some details:

You can create a hash that has the method names (as strings) as keys,
and the same names (as symbols) as the corresponding values, e.g.:

method_map = { "foo" => :foo, "bar" => :bar }
# Insert code to read and parse your input command here - results in
the command word (without the slash) being stored in the variable
'cmd', and the rest of the args in the variable 'args'; code is
straightforward, so omitting for brevity.
# Then:

if method_map(cmd)
obj.send(method_map[cmd], args)
else
raise StandardError, "Unrecognized command #{cmd}"
end

Note: The if condition might be wrong Ruby syntax - I've been
switching between writing Python and Ruby pretty rapidly in the last
few weeks while working on my projects - and don't remember right now
what a reference to a hash element by key returns when the key doesn't
exist in the hash (in Ruby, and am not at my machine right now) - I'm
assuming it returns nil, in which case the code shown should work, but
could be that I'm confusing it with the way it works in Python - where
it returns None (Python equivalent to Ruby's nil) and in Ruby it may
not return nil but throw an exception or whatever. Sorry about that.
But shouldn't be a problem - just check the Ruby docs or even just, at
an irb prompt, do:

[].methods.sort

This will show you the methods of the Hash class from which it should
be easy to figure out what method can be used to test for the presence
of a key in a hash. Modify the if statement accordingly.

An even simpler way may be:

obj.send(cmd.to_sym, args)

In all the above code, I'm assuming that obj is an object of a class
that implements all the methods needed to handle the commands
supported.

HTH
Vasudev Ram
http://www.dancingbison.com
http://jugad.livejournal.com
http://sourceforge.net/projects/xtopdf
 
V

vasudevram

Check out the __send__ method, which lets you call a method whose name
is in a variable:
obj.__send__(method_name, args)
- Show quoted text -

Tim Hunter is right. Just adding some details:

You can create a hash that has the method names (as strings) as keys,
and the same names (as symbols) as the corresponding values, e.g.:

method_map = { "foo" => :foo, "bar" => :bar }
# Insert code to read and parse your input command here - results in
the command word (without the slash) being stored in the variable
'cmd', and the rest of the args in the variable 'args'; code is
straightforward, so omitting for brevity.
# Then:

if method_map(cmd)
obj.send(method_map[cmd], args)
else
raise StandardError, "Unrecognized command #{cmd}"
end

Note: The if condition might be wrong Ruby syntax - I've been
switching between writing Python and Ruby pretty rapidly in the last
few weeks while working on my projects - and don't remember right now
what a reference to a hash element by key returns when the key doesn't
exist in the hash (in Ruby, and am not at my machine right now) - I'm
assuming it returns nil, in which case the code shown should work, but
could be that I'm confusing it with the way it works in Python - where
it returns None (Python equivalent to Ruby's nil) and in Ruby it may
not return nil but throw an exception or whatever. Sorry about that.
But shouldn't be a problem - just check the Ruby docs or even just, at
an irb prompt, do:

[].methods.sort

This will show you the methods of the Hash class from which it should
be easy to figure out what method can be used to test for the presence
of a key in a hash. Modify the if statement accordingly.

An even simpler way may be:

obj.send(cmd.to_sym, args)

In all the above code, I'm assuming that obj is an object of a class
that implements all the methods needed to handle the commands
supported.

HTH
Vasudev Ramhttp://www.dancingbison.comhttp://jugad.livejournal.comhttp://sourceforge.net/projects/xtopdf- Hide quoted text -

- Show quoted text -

Forgot to add this (which I checked online before writing the previous
post):

http://www.rubycentral.com/book/ref_c_object.html

Check out the __send__ and send method descriptions at that link.
__send__ is the same as send, its provided as an alternative in case
your class already has a send method of its own.

- Vasudev
 

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

Forum statistics

Threads
474,262
Messages
2,571,310
Members
47,976
Latest member
SheriBolli

Latest Threads

Top