Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Curious about a quirk with the special variable, $0

by mrdurtal (Scribe)
on Jan 31, 2012 at 10:39 UTC ( #950943=perlquestion: print w/replies, xml ) Need Help??

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

I will admit from the start that these may be some of those "dumb a**" questions that some people scowl at, but I'm curious. I was setting up a little demonstration program and I mistyped the following code and got what was a curious output at the time.

First the code (on a HP Netbook running Trisquel/Slaine, Libre-Linux, with Perl 5.10):

#!/usr/bin/perl #forcount use strict; use warnings; for (my $count = $0; $count < 10; $count++) { print "$count\n"; }

I had not noticed that I had initialised the count with a "$0" instead of "0". I had run "perl -c forcount" and syntax was ok (I regularly forget semicolons). Then, I ran the program and got the following output:

Argument "forcount" isn't numeric in numeric lt (<) at forcount line 5 +. forcount 1 2 3 4 5 6 7 8 9

I realised that I had fouled up the initialisation, but was interested to find the filename printed instead of the expected "0".

So, after a bit of investigation, here are my remaining questions:

a) What is the actual purpose of the special scalar variable, $0, which holds the filename of the script (I have read perlvar, but still don't understand the significance);

b) Did I not get a warning about the undeclared variable because it was being assigned to a declared variable, or did I not get it because it was a special variable such as $_ and why should this be the case; and,

c) Did the count iterate to 1..9 because the special scalar variable, $0, was treated as zero due to the numeric lt (<) operator? Or, in other words, how was the condition able to be evaluated if it did not conform to initial expectations by being non-numeric?

I apologise in advance for the "baby Perl" questions.

:There is more than one way to @verb a cat:

Replies are listed 'Best First'.
Re: Curious about a quirk with the special variable, $0
by tobyink (Canon) on Jan 31, 2012 at 11:17 UTC

    a) It's often useful to know what name your script has. For example:

    my $input_file = shift @ARGV; my $output_file = shift @ARGV; die "Usage: $0 INPUT OUTPUT\n" unless defined $input_file && defined $output_file;

    OK, you could replace $0 by hard-coding your script's filename, but what if somebody goes and renames your script - then your helpful error message is not so helpful anymore.

    jethro also mentions scripts that do different things depending on what they're named. (And you'd typically give the script multiple names using symbolic links on Unix-like filesystems.) lwp-request is a commonly installed example of a script that does precisely that.

    Lastly, on some operating systems it is possible to assign to $0. That is, you can do:

    $0 = "blah";

    And when people look at a list of processes running on the system (e.g. the top or ps commands on Linux) they'll see "blah" instead of the real name of the script. This is occasionally useful. For example, you have a script "http-server.pl" which opens up an HTTP server on a random TCP port. Then you just do:

    $0 = "http-server.pl [port $port]";

    And then the port it's serving on is shown in top and ps, which will be useful if you're running several HTTP servers at once, and need to check how much memory they are each consuming.

    b) special variables, like $0 are pre-declared. You don't need to declare them.

    c) Perl doesn't differentiate between numeric and other scalar values (e.g. strings) unless it really has to. Strings that don't look like a number are treated as "0" if used in a numeric context.

    Thus, usually $0 will equal 0 if used in a numeric context. However, try renaming your script to "4count.pl" and you'll notice that its behaviour changes.

Re: Curious about a quirk with the special variable, $0
by jethro (Monsignor) on Jan 31, 2012 at 11:02 UTC

    a) you can create scripts that do different things if named differently (either via linking or renaming the script file). Also I think the path is included so you know where the script is located

    b) Since $0 and a few other variables are available in every script they are predeclared. Otherwise you would have to start every script with a long list of special variables

    c) Yes, in numeric context a non-numeric value evaluates to 0.  perl -e 'print "test"+0;' will print 0

Re: Curious about a quirk with the special variable, $0
by ikegami (Pope) on Jan 31, 2012 at 12:14 UTC

    a) What is the actual purpose of the special scalar variable, $0, which holds the filename of the script

    You've answered your own question. Its purpose is to provide the file name of the script.

    b) Did I not get a warning about the undeclared variable

    The variable has a value, which means it exists, which means it has been defined, which means it has been declared. Just not by you.

    c) Did the count iterate to 1..9 because the special scalar variable, $0, was treated as zero due to the numeric lt (<) operator?

    The value in $0 (the script's file name) was treated as zero because the numerical value of a string that doesn't look like a number is zero. "56" + "4" + "abc" is equal to 60 (although you'll get a warning if they're on as they should be).

Re: Curious about a quirk with the special variable, $0
by GrandFather (Saint) on Jan 31, 2012 at 20:21 UTC

    As an aside: for my $count (0 .. 9) is more Perlish, safer and easier to read than using a C for loop to do the same job.

    True laziness is hard work

      Very cool, crisp, thanks. Is it safer because it reduces the risk of a typo? Or, is there something in the actual interpretation/compiling phase that can go wrong?

      :There is more than one way to @verb a cat:
Re: Curious about a quirk with the special variable, $0
by toolic (Bishop) on Jan 31, 2012 at 17:55 UTC
Re: Curious about a quirk with the special variable, $0
by Anonymous Monk on Jan 31, 2012 at 10:55 UTC

    I will admit from the start ... interested to find the filename printed instead of the expected "0".

    Dang, dat don soun like no good english :D (I actually don't know, just sounds, well, interesting to me :)

    FWIW, its all good, at least you're trying , to learn (as opposed just finish some program) :)

    a) What is the actual purpose of the special scalar variable, $0, which holds the filename of the script (I have read perlvar, but still don't understand the significance);

    That is the purpose, the hold the name of the script (hey, people want to know what it is, if they can )

    b) Did I not get a warning about the undeclared variable because it was being assigned to a declared variable, or did I not get it because it was a special variable such as $_ and why should this be the case; and,

    What undeclared variable, $0? Perl declares/defines/initializes $0 for you, its a pre-defined global variable

    c) Did the count iterate to 1..9 because the special scalar variable, $0, was treated as zero due to the numeric lt (<) operator? Or, in other words, how was the condition able to be evaluated if it did not conform to initial expectations by being non-numeric?

    This is equivalent to that for loop

    #!/usr/bin/perl -- use strict; use warnings; { my $count = $0; LOOOOOP: while(1){ print "$count\n"; if( not ( $count < 10 ) ){ last LOOOOOP ; } else { $count++; } } undef $count; } __END__ $ perl junk junk Argument "junk" isn't numeric in numeric lt (<) at junk line 7. 1 2 3 4 5 6 7 8 9 10

    Do you get it now?

    Try another

    #!/usr/bin/perl -- use strict; use warnings; { my $count = $0; LOOOOOP: { print "$count\n"; if( not ( $count < 10 ) ){ goto NO_MORE_LOOP; } else { $count++; goto LOOOOOP; } } NO_MORE_LOOP: undef $count; }

    I apologise in advance for the "baby Perl" questions.

    This free book covers this level of experience :) http://learn.perl.org/books/beginning-perl/

Re: Curious about a quirk with the special variable, $0
by mrdurtal (Scribe) on Feb 01, 2012 at 01:05 UTC

    Thanks folks.

    OK...UFDAH moment re: PREdeclared viable...what was I not thinking!

    I get that the difference would be with 4count verses forcount. Perl accepts the 4 as a number in the context and counts from there.

    Semi-UFDAH moment with $0 and ps. Now I get it. I'll try it when I get home from work to see if my OS will support the assignment of a new name from within the program and how that is picked up with HTOP.

    I'll also try the error approach. I like learning from the system.

    Your generosity and patience much appreciated!

    :There is more than one way to @verb a cat:

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://950943]
Approved by marto
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (6)
As of 2021-01-21 17:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Notices?