[30533] in Perl-Users-Digest

home help back first fref pref prev next nref lref last post

Perl-Users Digest, Issue: 1776 Volume: 11

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Wed Aug 6 21:14:23 2008

Date: Wed, 6 Aug 2008 18:14:13 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)

Perl-Users Digest           Wed, 6 Aug 2008     Volume: 11 Number: 1776

Today's topics:
        subcommand within Perl script <slick.users@gmail.com>
    Re: subcommand within Perl script <tzz@lifelogs.com>
    Re: subcommand within Perl script <slick.users@gmail.com>
    Re: subcommand within Perl script <ben@morrow.me.uk>
    Re: subcommand within Perl script <tzz@lifelogs.com>
    Re: subcommand within Perl script <slick.users@gmail.com>
    Re: subcommand within Perl script <ben@morrow.me.uk>
    Re: subcommand within Perl script <slick.users@gmail.com>
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

----------------------------------------------------------------------

Date: Wed, 6 Aug 2008 12:29:15 -0700 (PDT)
From: Slickuser <slick.users@gmail.com>
Subject: subcommand within Perl script
Message-Id: <cc7f8487-b1b4-42cd-971a-65e8adcde079@b38g2000prf.googlegroups.com>

I am trying to use Getopt::Long to get user input arguments.

>game.pl start mode:easy
>game.pl stop
>game.pl start mode:hard
>game.pl exit

If user input game.pl start mode:easy it will go to the start function
with mode:easy for options.

I'm not sure how to start it. Can you guys give me some hints. I have
some code below.


use strict;
use warnings;
use Getopt::Long;

&main;

sub main
{
	my (@CMDS);

	my $subcmds =
	{
		#game start -mode:easy
		"start" =>
		{
			'sub'		=> \&subcmd_start,
			'getopt'	=> ["-mode|m=s"],
		},

		";" =>
		{
			'sub' => \&subcmd_no_func,
		}

	};


	foreach my $arg_func (@ARGV)
	{
		if (exists $subcmds->{$arg_func})
		{
			push(@CMDS, [$arg_func]);
			next;
		}
		#else
		#{
		#	print "AAAAAAA \n";
		#}
	}

	foreach my $cmd (@CMDS)
	{
		#&exe_cmd($subcmds, $cmd->[0], $cmd->[1]);
	}


	return 1;
}

sub exe_cmd
{


}

sub subcmd_start
{
	print "Starting... \n";

}


sub subcmd_no_func
{
	print "No sub function... \n";

}


------------------------------

Date: Wed, 06 Aug 2008 14:44:31 -0500
From: Ted Zlatanov <tzz@lifelogs.com>
Subject: Re: subcommand within Perl script
Message-Id: <86wsiuhqsg.fsf@lifelogs.com>

On Wed, 6 Aug 2008 12:29:15 -0700 (PDT) Slickuser <slick.users@gmail.com> wrote: 

S> I am trying to use Getopt::Long to get user input arguments.
>> game.pl start mode:easy
>> game.pl stop
>> game.pl start mode:hard
>> game.pl exit

S> If user input game.pl start mode:easy it will go to the start function
S> with mode:easy for options.

S> I'm not sure how to start it. Can you guys give me some hints. I have
S> some code below.

You're not using Getopt::Long in your code, you just import it.

Since -mode will imply you want to start, you can get rid of -start:

# untested but copied from working code

my %options =
 (
# put your defaults here
 );

GetOptions (
	    \%options,
	    "mode|m=s",
	    "stop",
	    "exit",
	   );

if (exists $options{stop})
{
 ... stop logic ...
}

if (exists $options{exit})
{
 ... exit logic ...
}

if (exists $options{mode})
{
 ... start logic with $options{mode} ...
}


------------------------------

Date: Wed, 6 Aug 2008 12:50:19 -0700 (PDT)
From: Slickuser <slick.users@gmail.com>
Subject: Re: subcommand within Perl script
Message-Id: <128299c4-4e2d-4529-bf55-00faa46af725@w24g2000prd.googlegroups.com>

game.pl start -mode:easy
game.pl stop
game.pl start -mode:hard
game.pl exit

I would like to use multiple arguments, how would that work?
Such as:

game.pl start -mode:easy -cheat:off -player:3 -name:"Jen,Josh,Kim"

All these are optional: -mode:easy -cheat:off -player:3 -
name:"Jen,Josh,Kim".
By default it will start with easy, cheat off, player 1, Ben.

Thanks.


On Aug 6, 12:44 pm, Ted Zlatanov <t...@lifelogs.com> wrote:
> On Wed, 6 Aug 2008 12:29:15 -0700 (PDT) Slickuser <slick.us...@gmail.com> wrote:
>
> S> I am trying to use Getopt::Long to get user input arguments.
>
> >> game.pl start mode:easy
> >> game.pl stop
> >> game.pl start mode:hard
> >> game.pl exit
>
> S> If user input game.pl start mode:easy it will go to the start function
> S> with mode:easy for options.
>
> S> I'm not sure how to start it. Can you guys give me some hints. I have
> S> some code below.
>
> You're not using Getopt::Long in your code, you just import it.
>
> Since -mode will imply you want to start, you can get rid of -start:
>


> # untested but copied from working code
>
> my %options =
>  (
> # put your defaults here
>  );
>
> GetOptions (
>             \%options,
>             "mode|m=s",
>             "stop",
>             "exit",
>            );
>
> if (exists $options{stop})
> {
> ... stop logic ...
>
> }
>
> if (exists $options{exit})
> {
> ... exit logic ...
>
> }
>
> if (exists $options{mode})
> {
> ... start logic with $options{mode} ...
>
> }



------------------------------

Date: Wed, 6 Aug 2008 20:48:57 +0100
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: subcommand within Perl script
Message-Id: <9qbpm5-db8.ln1@osiris.mauzo.dyndns.org>


Quoth Slickuser <slick.users@gmail.com>:
> I am trying to use Getopt::Long to get user input arguments.
> 
> >game.pl start mode:easy
> >game.pl stop
> >game.pl start mode:hard
> >game.pl exit

If you want options looking like that, you don't want Getopt::Long :).

> If user input game.pl start mode:easy it will go to the start function
> with mode:easy for options.
> 
> I'm not sure how to start it. Can you guys give me some hints. I have
> some code below.
> 
> 
> use strict;
> use warnings;
> use Getopt::Long;
> 
> &main;

Don't call subs with & unless you need to.

> sub main
> {
> 	my (@CMDS);
> 
> 	my $subcmds =
> 	{
> 		#game start -mode:easy
> 		"start" =>
> 		{
> 			'sub'		=> \&subcmd_start,
> 			'getopt'	=> ["-mode|m=s"],
> 		},

OK, you're building a dispatch table: that's a good start. Personally I
would put the subs directly in the table, like

    my $subcmds = {
        start => {
            getopt => ['-mode|m=s'],
            sub    => sub {
                # contents of &subcmd_start here
            },
        },
    };

rather than giving them separate names, but that's not important.

> 		";" =>

I'm not sure what this entry is for: are you expecting users to invoke
the program like

    game ";"

?

> 	foreach my $arg_func (@ARGV)

I don't think you want a for loop here. AFAICT, you just want to
dispatch on the first argument, and pass the rest; this looks like
    
    my $cmd = shift @ARGV;
    $subcmds->{$cmd} or die "no such command: $cmd\n";
    $subcmds->{$cmd}{sub}->(@ARGV);

Ben

-- 
For the last month, a large number of PSNs in the Arpa[Inter-]net have been
reporting symptoms of congestion ... These reports have been accompanied by an
increasing number of user complaints ... As of June,... the Arpanet contained
47 nodes and 63 links. [ftp://rtfm.mit.edu/pub/arpaprob.txt] * ben@morrow.me.uk


------------------------------

Date: Wed, 06 Aug 2008 15:57:54 -0500
From: Ted Zlatanov <tzz@lifelogs.com>
Subject: Re: subcommand within Perl script
Message-Id: <868wv9j1yl.fsf@lifelogs.com>

On Wed, 6 Aug 2008 12:50:19 -0700 (PDT) Slickuser <slick.users@gmail.com> wrote: 
S> On Aug 6, 12:44 pm, Ted Zlatanov <t...@lifelogs.com> wrote:
>> On Wed, 6 Aug 2008 12:29:15 -0700 (PDT) Slickuser <slick.us...@gmail.com> wrote:
>> 
S> I am trying to use Getopt::Long to get user input arguments.
>> 
>> >> game.pl start mode:easy
>> >> game.pl stop
>> >> game.pl start mode:hard
>> >> game.pl exit
>> 
S> If user input game.pl start mode:easy it will go to the start function
S> with mode:easy for options.
>> 
S> I'm not sure how to start it. Can you guys give me some hints. I have
S> some code below.
>> 
>> You're not using Getopt::Long in your code, you just import it.
>> 
>> Since -mode will imply you want to start, you can get rid of -start:
>> 


>> # untested but copied from working code
>> 
>> my %options =
>> (
>> # put your defaults here
>> );
>> 
>> GetOptions (
>> \%options,
>> "mode|m=s",
>> "stop",
>> "exit",
>> );
>> 
>> if (exists $options{stop})
>> {
>> ... stop logic ...
>> 
>> }
>> 
>> if (exists $options{exit})
>> {
>> ... exit logic ...
>> 
>> }
>> 
>> if (exists $options{mode})
>> {
>> ... start logic with $options{mode} ...
>> 
>> }

S> game.pl start -mode:easy
S> game.pl stop
S> game.pl start -mode:hard
S> game.pl exit

S> I would like to use multiple arguments, how would that work?
S> Such as:

S> game.pl start -mode:easy -cheat:off -player:3 -name:"Jen,Josh,Kim"

S> All these are optional: -mode:easy -cheat:off -player:3 -
S> name:"Jen,Josh,Kim".
S> By default it will start with easy, cheat off, player 1, Ben.

Please don't top-post.

You can add any options to the GetOptions parameters, e.g. add
"player=i" to have a "-player 3" option.  Put "player => 1" in %options
if you want a default player value.  If you want colons to set the
options, as your examples show, you'll have to look at the Getopt::Long
docs or write your own parser.

If I understand your player example, what you really want there is
"player|p=s@" which will put multiple players in an array reference in
%options.  So you'll be able to say

my $player_one = $options{player}->[0];

Please see the Getopt::Long documentation.  "Options with multiple
values" is right after the introduction.

Ted


------------------------------

Date: Wed, 6 Aug 2008 14:11:29 -0700 (PDT)
From: Slickuser <slick.users@gmail.com>
Subject: Re: subcommand within Perl script
Message-Id: <c42d3bea-0ab4-4a3e-9c90-8f428118b727@o40g2000prn.googlegroups.com>

Ben,

Thanks for the suggestion. I will follow that method and ignore that
module.
Once I'm in the function, I can search for the options.

How can I fixed this error?

>game.pl
Use of uninitialized value in hash element at C:\game.pl line 30.
Use of uninitialized value in hash element at C:\game.pl line 31.
No sub function...

>game.pl start -mode:easy
Starting...
The rest are options: -mode:easy


use strict;
use warnings;

my @CMDS = @ARGV;

main();

sub main
{

	my $subcmds =
	{
		#game start -mode:easy
		"start" =>
		{
			'sub'		=> \&subcmd_start,
			'getopt'	=> ["-mode|m=s"],
		},

		"" =>
		{
			'sub' => \&subcmd_no_func,
		}

	};


	my $cmd = shift @CMDS;
	   $subcmds->{$cmd} or die "no such command: $cmd\n";
	   $subcmds->{$cmd}{sub}->(@CMDS);

	return 1;
}


sub subcmd_start
{
	print "Starting... \n";

	print "The rest are options: @CMDS \n";



}


sub subcmd_no_func
{
	print "No sub function... \n";

}




------------------------------

Date: Wed, 6 Aug 2008 22:26:46 +0100
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: subcommand within Perl script
Message-Id: <mhhpm5-0mb.ln1@osiris.mauzo.dyndns.org>


Quoth Slickuser <slick.users@gmail.com>:
> Ben,
> 
> Thanks for the suggestion. I will follow that method and ignore that
> module.
> Once I'm in the function, I can search for the options.

You can use Getopt::Long to do this, within each function, if you like.
You could also use G:L to process the remainder of @ARGV before you call
the sub, and pass the parsed options.

> How can I fixed this error?
> 
> >game.pl
> Use of uninitialized value in hash element at C:\game.pl line 30.
> Use of uninitialized value in hash element at C:\game.pl line 31.

If you pass no arguments, then @ARGV has no values, and when you try to
shift one off you get undef. There are several ways to fix this:

    my $cmd = (shift @ARGV || '');

will default to using the empty string; however, then both

    game.pl ""

and

    game.pl 0

will be treated as 'no arguments', since 0 is a false value in Perl. If
you're OK with the former but not the latter, you can use

    my $cmd = shift @ARGV;
    defined $cmd or $cmd = '';

or (if you are using 5.10)

    my $cmd = (shift @ARGV // '');

If neither is OK, you can use

    @ARGV or return subcmd_no_func();
    my $cmd = shift @ARGV;

which will only call subcmd_no_func if no arguments are supplied.

Ben

-- 
#!/bin/sh
quine="echo 'eval \$quine' >> \$0; echo quined"
eval $quine
#                                                        [ben@morrow.me.uk]


------------------------------

Date: Wed, 6 Aug 2008 16:30:19 -0700 (PDT)
From: Slickuser <slick.users@gmail.com>
Subject: Re: subcommand within Perl script
Message-Id: <f574e60d-ad6f-4228-a395-1efb0f115034@r15g2000prh.googlegroups.com>

I will follow this model. Thanks..

use strict;
use warnings;
use Getopt::Long;

main();

sub main
{

	my $subcmds =
	{
		#game start -mode "easy"
		"start" =>
		{
			'sub'		=> \&subcmd_start,
			'getopt'	=> ["-mode|m=s"],
		},

		"" =>
		{
			'sub' => \&subcmd_no_func,
		}

	};


	my $cmd = shift @ARGV;
	defined $cmd or $cmd = '';
	$subcmds->{$cmd} or die "no such command: $cmd\n";
	$subcmds->{$cmd}{sub}->(@ARGV);

	return 1;
}


sub subcmd_start
{
	GetOptions(
		'mode:s' 	=>	\my $opt_mode,
		'name:s' 	=> 	\my $opt_name,
		'player:i' 	=> 	\my $opt_player,
		'cheat:s'	=> 	\my $opt_cheat
	);

	print "Starting... \n";

	if (defined $opt_cheat)
	{
		print "Cheat: $opt_cheat \n";
	}

}


sub subcmd_no_func
{
	print "No sub function... \n";

}




------------------------------

Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin) 
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>


Administrivia:

#The Perl-Users Digest is a retransmission of the USENET newsgroup
#comp.lang.perl.misc.  For subscription or unsubscription requests, send
#the single line:
#
#	subscribe perl-users
#or:
#	unsubscribe perl-users
#
#to almanac@ruby.oce.orst.edu.  

NOTE: due to the current flood of worm email banging on ruby, the smtp
server on ruby has been shut off until further notice. 

To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.

#To request back copies (available for a week or so), send your request
#to almanac@ruby.oce.orst.edu with the command "send perl-users x.y",
#where x is the volume number and y is the issue number.

#For other requests pertaining to the digest, send mail to
#perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
#sending perl questions to the -request address, I don't have time to
#answer them even if I did know the answer.


------------------------------
End of Perl-Users Digest V11 Issue 1776
***************************************


home help back first fref pref prev next nref lref last post