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

Hello... Please take a look at the following snippet of code...
if( $#ARGV == 0 ) { my ($date) = $ARGV[0]; } else { # obtain the date from the previous day in the format YYYYMMDD my($yr,$mo,$day) = (localtime( time - 60*60*(12+(localtime)[2])))[5 +,4,3]; #my $date = sprintf "%04d%02d%02d",1900+$yr,1+$mo,$day; # for test purposes!!! my $date = "20010912"; } # Output the header to the info file. # ----------------------------------- print OUTREP "\nThe following trades from " . $date . " finished with + a ticket status of 11\n\n";
Perl gives me the following error:
Global symbol "date" requires explicit package name at ebOrdHist.pl li +ne 60. Execution of ebOrdHist.pl aborted due to compilation errors.

Replies are listed 'Best First'.
Re: Copying a value from an element in the ARGV array to a variable...
by arturo (Vicar) on Sep 17, 2001 at 19:54 UTC

    Just a note: you can test whether @ARGV has any members with the idiomatic

    my $date; if (@ARGV) { $date = $ARGV[0]; }

    Two things: @ARGV gets evaluated in a scalar context, which means that what is checked is the *number* of elements in the array; if that number is *not* 0 (i.e. if there are any elements in the array), the test evaluates to true, and the block will be executed.

    Second note : the *declaration* of $date occurs outside the braces, so when you set $date inside the braces, that change will be visible to other code outside the braces. When you use my inside a set of braces, you're creating a *new* variable that is only visible to code inside the braces. You can see how this works with

    my $date = "bar"; print "Outside 1 : $date\n"; { my $date = "foo"; print "Inside : $date\n"; } print "Outside 2 : $date\n";

    Incidentally, you can make your $date setting very compact by using || or the "ternary operator" (see perlop):

    my $date = $ARGV[0] || yesterday(); sub yesterday { my ($yr,$mo,$day) = (localtime( time - 86400 ))[5,4,3]; return sprintf "%04d%02d%02d",1900+$yr,1+$mo,$day; }

    if $ARGV[0] evaluates to false ( because it doesn't exist, or was 0 ), then $date gets set to what the yesterday sub returns.

    HTH. /msg me if you need anything explained.

    perl -e 'print "How sweet does a rose smell? "; chomp ($n = <STDIN>); +$rose = "smells sweet to degree $n"; *other_name = *rose; print "$oth +er_name\n"'
Re: Copying a value from an element in the ARGV array to a variable...
by davorg (Chancellor) on Sep 17, 2001 at 19:40 UTC
Re: Copying a value from an element in the ARGV array to a variable...
by mr.nick (Chaplain) on Sep 17, 2001 at 20:02 UTC
    Just to build on arturo's comment of using the ternary || operator: if you have (or plan to have) multiple arguments, then something along these lines might work better for you:
    my $date = @ARGV ? shift @ARGV : yesterday();
    That way you can easily inline other arguments:
    my $arg1 = @ARGV ? shift @ARGV : 'default value'; my $date = @ARGV ? shift @ARGV : yesterday(); my $arg2 = @ARGV ? shift @ARGV : 'other value';

    mr.nick ...