Ahbeyra has asked for the wisdom of the Perl Monks concerning the following question:

How would i go about making a script work with multiple-arg commands, like when you use the chatterbox and type "/tell ahbeyra moo", how do you get it to recognized the different parts of it? and does it have to do with the /?

Replies are listed 'Best First'.
Re: multiple-arg commands
by blackmateria (Chaplain) on Oct 24, 2001 at 02:01 UTC
    The question has different answers depending on the meaning of "multiple-arg."

    If you mean "multiple command-line arguments," as in perl myscript.pl file1 file2 file3 where file[1-3] are the "multiple arguments," then there's a global array @ARGV that has the one element per argument. In this example, $ARGV[0] eq 'file1', $ARGV[1] eq 'file2', etc. The name of the script is in the special variable $0.

    If you mean how do you take a string like "/tell ahbeyra moo" that someone would type into the chatterbox, and parse it into separate words (based on spaces for example), one simple way you could do this is with split. As in, my @args = split /\s+/, $string, where $string had the "/tell" command in it. This would make @args an array with 3 elements, "/tell", "ahbeyra", and "moo." You will get empty strings at the beginning of the array if $string starts with spaces, so be careful there.

    Or, if you want to parse a string into, say, "/tell" and the rest of the message, you can use regular expressions with m// and friends, like my ($cmd, $phrase) = ($string =~ m[\s*(/\w+)\s+(.*)])

    This will put "/tell" into $cmd (in the example) and "ahbeyra moo" into $phrase. You should really look into perlre if you're interested in this sort of thing; it's a wealth of information (oftentimes too much ;)

    Hope this helps!

Re: multiple-arg commands
by mandog (Curate) on Oct 24, 2001 at 01:49 UTC

      ... or even Getopt::Declare that is not claimed to be "POSIX syntax with GNU extension"-compatible but IMHO much more powerfull and has more informative diagnostics (thanks TheDamian again!).

      -- brother ab
Re: multiple-arg commands
by Fletch (Bishop) on Oct 24, 2001 at 06:41 UTC

    You just write a parser to do what you want. In the chatterbox, the input field is passed as one big string when the form is submitted. The stuff implementing the chatterbox parses the line and does the right thing.

    If you don't have things already split, it depends on how you want to parse things. Going with your chatterbox example, you could always look at the first character of the line to see if it starts with a `/'. If it doesn't default to passing the line to your say routine (or whatever). If it did start with `/', then do something like:

    my %handlers = ( tell => \&tell_user, msg => \&tell_user, chatoff => \&toggle_chat, chaton => \&toggle_chat, moo => \&order_cheese, ); my( $command, $rest ) = split( /\s+/, $line, 2 ); $command =~ s{^/}{}; # throw away / if( exists( $handlers{ lc($command) } ) { $handlers{ lc($command) }->( $rest ); } else { send_error( "Unknown command `$command'" ); }

    Each of the handlers would be passed the rest of the line to do with as they wish. tell_user would probably do another split to pull off the target and use the rest as the message to send, while order_cheese might take the rest of the line as a type of cheese and the amount to order.

    For more inspiration, take a look at how the CPAN.pm module's shell is implemented and how it parses lines.

      Thanks! that makes perfect sense, and it answered my second, unasked, question too, good job!

      ------------------------------- I love the smell of pastures in the morning... /tell ahbeyra moo