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

Hello fellow inmates I've got what is probably the dumbest question ever asked in these hallowed halls but I can't help it - it's began to annoy me so much I feel compelled to ask! (Even if I'm demoted to sewer cleaning!) The following code is just a wee test that I set up to try and have multiple actions after an 'or' statement. In a subroutine I would like to print an error message and then return 0 (False) on encountering a write error - foolish ignorant optimism I know but if you can't have your dreams................
#!/usr/bin/perl -w # sub fred { use strict ; # my $file = 'xxrcdisnaeexist' ; my $TV = 0 ; # open IP, $file or (print "\n\tNo kin d\n" , print "\n\tI bet ye dinna see this\n" , return 0 ) ; # if ($TV) { print "\n\tIt's Twoo It's Twoo\n" ; } # } $fred or die "\n\tThis failed min!!!\n" ;
On running this, I don't get all the expected output -
$ xxrcor.pl Name "main::IP" used only once: possible typo at xxrcor.pl line 9. This failed min!!! $
The multiple actions after the or don't appear to have worked - though clearly a 0 (False) HAS been returned as desired! Why have my print messages failed to appear? If this IS the dumbest question asked I apologise but I can't see why this is happening and It's becoming irritating!
Thanks,
Ronnie

Replies are listed 'Best First'.
Re: 'or' Bug Bear
by cog (Parson) on Feb 10, 2005 at 11:49 UTC
    It's not $fred, it's fred().

    fred is a subroutine, not a variable. You're confusing things, because you're probably thinking that you want the scalar value that the subroutine returns.

    Try this, it might make more sense to you:

    my $fred = fred(); $fred or die "\n\tThis failed min!!!\n" ;

    HTH :-)

      i think the "$" should indicate the perl-shell.

      Update: because when you run the code with the "$" then you get
      Variable "$fred" is not imported at ... (Did you mean &fred instead?) Global symbol "$fred" requires explicit package name at ... Execution of test.pl aborted due to compilation errors.
      instead of the OPīs output.

      Update: Ah. no. itīs the use strict in the wrong place that allows that "$fred". Above error only arises when you move the "use strict;" outside the subroutine. So in the OPīs code, the subroutine does not get called at all!!

      holli, /regexed monk/
        I don't think so, because then the subroutine would have to be called somewhere. Plus, it seems by the rest of the post that the script name is "xxrcor.pl", and it seems that it is called from a bash or something similar.

        But it makes sense, it could be...

Re: 'or' Bug Bear
by cog (Parson) on Feb 10, 2005 at 11:52 UTC
    As for the multiple actions, instead of

    or (print ...; print ...)

    use this:

    or do {print ...; print ...}

    That should do the trick.

    One other thing, do use strict, but not inside the subroutine; put it on the top of the script.

      Note that the OP was using or (print ..., print ...), not or (print ...; print ...).

      While the do solution you provide is probably better, you can also do or (print(...), print(...)). The parentheses prevent the first print from eating everything that follows as its parameters.

Re: 'or' Bug Bear
by holli (Abbot) on Feb 10, 2005 at 11:52 UTC
    the problem here is, that the arguments for print are in list-context. Everything after print is gobbled into that list. this includes the "return". therefore it prints nothing.
    iīd rewrite the code like
    #!/usr/bin/perl -w use strict ; sub fred { # my $file = 'xxrcdisnaeexist' ; my $TV = 0 ; # unless ( open IP, $file ) { print "\n\tNo kin d\n", "\n\tI bet ye dinna see this\n"; return; } # if ($TV) { print "\n\tIt's Twoo It's Twoo\n" ; } # } fred or die "\n\tThis failed min!!!\n" ;
    holli, /regexed monk/
Re: Bug Bear - or
by dave_the_m (Monsignor) on Feb 10, 2005 at 12:12 UTC
    open IP, $file or (print "\n\tNo kin d\n" , print "\n\tI bet ye dinna see this\n" , return 0 ) ;

    That should be written thus:

    open IP, $file or do { print "\n\tNo kin d\n"; print "\n\tI bet ye dinna see this\n"; return 0};

    Dave.

Re: Bug Bear - or
by reneeb (Chaplain) on Feb 10, 2005 at 12:03 UTC
    use strict at the beginning of the script! It should tell you that you haven't declared the variable $fred...

    And you should invoke the subroutine like fred()
Re: 'or' Bug Bear
by MidLifeXis (Monsignor) on Feb 10, 2005 at 20:12 UTC

    Something everyone has missed thus far is that fred() will always return a false value. The if ($TV) statement will always fail, so if the subroutine gets past the open statement, there will still be an implied return of the last statement result, namely false.

    The die will always be called.

    --MidLifeXis