in reply to unexpected results using -s switch

With -s switch, then any switch to the script will be treated as boolean switch unless supplied with argument. So -foo will set $foo to 1, and -foo=anything will set $foo to anything.
$ cat foo.pl #!/usr/bin/perl -s use strict; use vars '$foo'; print $foo, "\n"; $ ./foo.pl -foo 1 $ ./foo.pl -foo=bar bar

Open source softwares? Share and enjoy. Make profit from them if you can. Yet, share and enjoy!

Replies are listed 'Best First'.
Re^2: unexpected results using -s switch
by mojodaddy (Pilgrim) on Aug 05, 2007 at 03:16 UTC
    Interesting. So when NOT supplying an argument, it doesn't matter if I have the -s at the top of the script and call the script with perl on the command line. I only have to pick one when I do supply an argument.

    Is there a mnemonic for remembering that? : )

      Expanding AM's reply, when we use shebang (#!/usr/bin/perl), we have an advantage to make our program "a real program" by turning our source file's execute bit on. In this case, the OS will call the correspondent interpreter program (perl in this case) to process the file in question, and all perl switches (-w, -s, -T, etc) are taken into account. So we're able to say,
      $ ./program.pl # or if it's in known PATH: $ program.pl
      Of course, this only applies if the underlying OS supports it, such as Linux.

      OTOH, we are of course able to call the perl interpreter directly and feed it with the source file. This way, we can provide some extra switches not exist in the shebang, or even overriding switches in the shebang. It also means that executing a source file this way doesn't require the shebang to be declared in the source file. However, the perl interpreter will consider it if it does exist.

      Having said that, I think you can assure yourself about that "pick one", regardless of using -s (with our without argument to your own swithces) or not. Now let me suggest you that, if you're really serious about providing command line arguments for your program, use the more elegant modules from CPAN for parsing the arguments for you. One of them is Getopt::Long that comes with the standard Perl distribution.

      $ cat foo.pl #!/usr/bin/perl use strict; use warnings; use Getopt::Long; my %opts; GetOptions(\%opts, 'foo=s', 'v'); # '=s' modifier means foo needs argument, and it can be # any string (another modifier is '=i' for integer.) print "foo = $opts{foo}, verbose = $opts{v}\n"; $ perl foo.pl --foo=bar -v foo = bar, v = 1 $ ./foo.pl --for=bar -v foo = bar, v = 1
      Now, I'd say "pick any" instead of "pick one" :-) You don't have to use a hash to store the arguments, you can use direct scalar.
      $ cat foo.pl #!/usr/bin/perl use strict; use warnings; use Getopt::Long; use vars qw($foo, $verbose); GetOptions('foo=s' => \$foo, 'v' => \$verbose); # '=s' modifier means foo needs argument, and it can be # any string (another modifier is '=i' for integer.) print "foo = $foo, verbose = $verbose\n"; $ perl foo.pl --foo=bar -v foo = bar, v = 1 $ ./foo.pl --for=bar -v foo = bar, v = 1
      See Getopt::Long for detail.

      Open source softwares? Share and enjoy. Make profit from them if you can. Yet, share and enjoy!

Re^2: unexpected results using -s switch
by oha (Friar) on Aug 06, 2007 at 09:27 UTC
    if i understood correctly, the matter is different:
    $ cat t.pl #!/usr/bin/perl print "foo=$foo\n"; $ perl t.pl -foo=bar foo=
    and that's is expected.
    $ cat t.pl #!/usr/bin/perl -s print "foo=$foo\n"; $ perl -s t.pl -foo=bar foo=bar
    and that's too, but:
    $ cat t.pl #!/usr/bin/perl -s print "foo=$foo\n"; $ perl t.pl -foo=bar foo=1
    if i call it without -s, but the shebang say -s, perl assign 1 which is neither bar or undef

    Oha

    update: with the help of dada i think we have figured out it was a bug in perl.c function init_argv_symbols. checking on dev.perl.org on latest 5.x sources seems fixed btw. could anyone confirm? it's long since i read C code...