in reply to Can this If/Else be condensed into a 1 liner with a trailing If?

I think I must be missing something about the if bit - it doesn't seem to do anything. If that's right, then you could get the same result with
print "$in was not a number!"; input() unless $in =~ /\d/;
which does get it on one line, though not, I agree, with a trailing if :). On the other hand if the line
$in;
is a line you need (perhaps an idiom I don't know - if so, what does it do? - in any event it has a certain classically simplicity about it) - then to get it on one line you could use the conditional operator, although there might be some pros and cons here I don't know about:
$in =~ /\d/ ? $in : print "$in was not a number!";
That doesn't let you call input(), but that's ok if you agree with lesstrat that it might get a bit ropey if you call input() from within input().

On the broader question of how to detect numbers, I find that what I usually want to isolate is everything that isn't not a number, so my favourite idiom is
$in !~ /\D/
But this question is much more complicated than one would think, as these and threads explain.

§ George Sherston

Replies are listed 'Best First'.
Re: Re: Can this If/Else be condensed into a 1 liner with a trailing If?
by suaveant (Parson) on Oct 02, 2001 at 18:07 UTC
    the $in...

    As you may or may not know, perl will return the last value in a subroutine it sees... so

    sub foo { 'foo'; }
    will return foo even without an explicit return 'foo';
    so in a case like the following
    print(foo(),"\n"); sub foo { if(1) { 'foo'; } else { 'bar'; } }
    foo will be printed, since it is the last real value perl saw in the subroutine, everything else was basically blank lines... BUT! one must be careful in this situation because if you ever come back and put code in after the if statement like
    print(foo(),"\n"); sub foo { if(1) { 'foo'; } else { 'bar'; } print STDERR 'fooed'; }
    then you will get 1, the return value of a successful print. most people use an explicit return unless the value they are returning is the last line of the sub, since it is then much harder to miss.

                    - Ant
                    - Some of my best work - Fish Dinner

      Hmm. I thought it might be something like that, but now instead of a nebulous feeling that it must be something to do with returning values I actually know how it works! Very educational - thanks for the explanation. My subroutines will be grateful too.

      So (just getting this straight, hoping my thought processes won't be too dull for others) in jerrygarciuh's case, if he replaces the if... else with
      print "$in was not a number!"; input() unless $in =~ /\d/;
      then the subroutine will return the number of characters chomped from $in, rather than $in itself. So in order to reduce the if... else loop to a single line, one wd have to do something like
      sub input { my $arrayref=shift; print "\nSo far you've guessed @$arrayref." if $arrayref; print "\nWhat is your guess?\n"; chomp <STDIN>; my $in=<STDIN>; print "$in wasn't a number!";input() unless $in =~ /\d/; }
      Would that work? Is it nicer? Have I learnt something from this exchange? (The answer to at least one of these questions is "yes".)

      § George Sherston
        Actually, not quite... remember
        print "$in wasn't a number!";input() unless $in =~ /\d/; # is the same as print "$in wasn't a number!"; input() unless $in =~ /\d/; # what you want is print("$in wasn't a number!"),input() unless $in =~ /\d/;
        See, with the comma, the unless contains the print and the input, with the ; it only contains the input(), and I'm not sure what will be returned in that case, so I would probably do...
        print("$in wasn't a number!"),return input() unless $in =~ /\d/;
        Just to be safe. (It might work properly anyway, I'd have to test)

        It should return $in otherwise... I think... my rule of thumb usually is, if I am not sure what will be returned, I use a return. I usually only leave out the return when my value is on the actual last line of the subroutine. Can save headaches... :)

                        - Ant
                        - Some of my best work - Fish Dinner

Re: Re: Can this If/Else be condensed into a 1 liner with a trailing If?
by {NULE} (Hermit) on Oct 02, 2001 at 20:25 UTC
    Hi,

    I personally love using the conditional operator. You just have to be careful with it. For example:

    #! /usr/local/bin/perl -w use strict; $a = 1; $b = 2; (1) ? $a = 3 : $b = 4; print "1) a = $a, b = $b\n"; (1) ? ($a = 3) : ($b = 4); print "2) a = $a, b = $b\n";
    displays:
    1) a = 4, b = 2 2) a = 3, b = 2
    Which may or may not be what you expect.

    Good luck!
    {NULE} PS I'm having issues with Opera again, please forgive me if I screw this post up (again.) Time for a new web-browser *sigh*.