Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

multiple commands before unless ?

by emilford (Friar)
on Jun 25, 2003 at 16:09 UTC ( [id://268892]=perlquestion: print w/replies, xml ) Need Help??

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

Is it possible to have multiple commands preceeding an unless test? I prefer to use the format

[do something] unless ([some case]);

when I am able to, but this time around, I need the [do something] to be multiple statements instead of just one. Is something like this possible:
(print "Program Error!" && exit(0)) unless ([case is true]);
I thought using the double &'s would allow multiple statements to be executed one after the other, but the above code prints nothing.

While I'm at it, I have a short script that replaces a specific line in a file. Is there a better way to do this than what I'll pseudo code below?
# open the file - read # swap the update_info=blah line to update_info=auto my @lines = map {s/^update_info=(?:\w+)/update_info=auto/; $_ } <FILE> +; # close file # open the file - write foreach (@lines) { print TOFILE; } # close file
Thanks.

Title edit by tye

Replies are listed 'Best First'.
Re: unless
by fglock (Vicar) on Jun 25, 2003 at 16:14 UTC
    do { commands; } unless $test;

    If you don't need the array, you can read-and-print:

    # open the file - read # open the file - write while( <FILE> ) { # swap the update_info=blah line to update_info=auto s/^update_info=(?:\w+)/update_info=auto/; print TOFILE $_; } # close file # close file
      I could also have done it this way, but I was interested in trying to use/learn about map. That's the main reason why I did it the way I did. Plus, map is just cool. ;-)
        print TOFILE map {s/^update_info=(?:\w+)/update_info=auto/; $_ } <FILE>;
Re: unless
by adrianh (Chancellor) on Jun 25, 2003 at 16:17 UTC
    Is it possible to have multiple commands preceeding an unless test?

    Use do:

    do {print "Program Error!"; exit(0)} unless [case is true];

    Although, personally, I would find the prefix variant of unless clearer if you're doing more than one thing.

    While I'm at it, I have a short script that replaces a specific line in a file. Is there a better way to do this than what I'll pseudo code below?

    Take a look at Tie::File - dead useful :-)

      The do{ } is exactly what I needed, however I want to avoid using modules in this case. Tie::File looks handy for other uses, but not what I'm doing at the moment. Anyone else have any other methods that don't require a module?
Re: multiple commands before unless ?
by Not_a_Number (Prior) on Jun 25, 2003 at 21:23 UTC

    You have a precedence issue.

    I recently happened upon an brilliant online tutorial on this subject, but I can't find the URL for the mo (the issue is nevertheless well addressed in chapter 2 of Simon Cozens' Beginning Perl available online at http://learn.perl.org/library/beginning_perl/3145_Chap02.pdf).

    The precedence issue was indeed (very succinctly) pointed out in fglock's reply above.

    Removing punctuation, and simplifying, your key line is: print "Program Error!" && exit(0) unless $case; Just change the && to and, and it'll work:

    my $case = 1; print 'Program Error' and exit(0) unless $case; print 'No problemo!'
    hth dave
      Is this the tutorial you were looking for?
        Yep, thanks. I should have known. MJD rules OK.
      It's amazing how precedence can throw you off like that. This reminds me of an error I had back in college. You'd think I'd have remembered to take this into consideration in this case. Thanks.
Re: unless
by Bilbo (Pilgrim) on Jun 25, 2003 at 16:20 UTC

    Try running this line:

    print "Yes\n" && exit;

    It probably doesn't do what you think it does. Now try this:

    (print "Yes\n") && (exit);

    The problem is, I think, that the first is interpreted as:

    print ("Yes\n" && exit);

    If the second operation (exit) is successful then this would print "1" for "true", except that since the second operation is exit it can't print anything because it's exited before it gets to the print statement.

      H:\>perl -e "print 'yes' and exit; print 'no' " yes H:\>perl -e "print 'yes' && exit; print 'no' " # nothing
Re: unless
by Itatsumaki (Friar) on Jun 25, 2003 at 16:17 UTC

    Try this:

    do { print "Program Error!"; exit(0); } unless ([case is true]);
    -Tats
Re: multiple commands before unless ?
by VSarkiss (Monsignor) on Jun 25, 2003 at 19:21 UTC

    Nobody mentioned this, so I will: If you're willing to change the order, you can use unless like if:

    unless ($something) { first_thing(); second_thing(); many_things(); }
    Personally, I think it looks a little better, but it's up to you. I just mentioned it because not everyone is aware that you can use unless in this fashion.

      I know of this fashion as well, but I wanted to use it in the other direction in this case. Thanks.
Re: unless
by crouchingpenguin (Priest) on Jun 25, 2003 at 17:12 UTC

    Or use the comma operator:

    #!/usr/bin/perl use strict; use warnings; use constant TRUE => 0; printf("System Error\n"), exit unless TRUE; print 'I should never be printed',"\n";

    Update: Changed code so it follows question example code.


    cp
    ----
    "Never be afraid to try something new. Remember, amateurs built the ark. Professionals built the Titanic."
      I don't see how this applies. I wasn't trying to print a variable, but rather print a string and then exit the script. Am I missing something.
Re: multiple commands before unless ?
by emilford (Friar) on Jun 26, 2003 at 16:23 UTC
    By the way, not many have commented on the other question. Is the way I'm doing this a good approach as far as using the map function to swap out the line I am looking for in the file? I know this can be done in quite a few different ways, but I want to limit the operations used. Also, no modules! Thanks.
      Saying "No modules" in this crowd is like waving a red flag at a bull.

      But that said, I would solve your original problem using the options in perlrun. For instance:

      perl -pi.bak -e 's/^update_info=(?:\w+)/update_info=auto/' your_file
      (Switch quotes to " for Windows.)
      Also, no modules!

      Why?

        I know modules are usually the way to go. I use modules for my own projects. I asked for a no-module solution because I'm not sure what modules are going to be installed on the systems that I work on. Things are very locked down, so I wouldn't be surprised if we were working on a less than standard build. If I had control over what modules were installed, than I'd be more than willing to use some of the mentioned modules.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others sharing their wisdom with the Monastery: (3)
As of 2024-04-19 18:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found