true false ? : expression thingy

Discussion in 'Perl Misc' started by Bigus, Jul 28, 2005.

  1. Bigus

    Bigus Guest

    I'm not sure what this method is called, which is perhaps why I've had no
    luck when searching around the web for info on it, but when you want a
    1-line alternative to an if...else.. construct, you can use the following
    syntax:

    $ctr > 3 ? $text = "yes" : $text = "no";

    that works fine, however, when I try this:

    my $incsubs;
    $line =~ /\ts/i ? $incsubs = 0 : $incsubs = 1;

    it doesn't work.. well, $incsubs equals 1 regardless whereas it works in the
    standard if...else.. construct.

    I guess this is because the regular expression doesn't return true/false, or
    sth like that.. is there a "trick" you can use to make this type of method
    work with regexps?

    Bigus
    Bigus, Jul 28, 2005
    #1
    1. Advertising

  2. Bigus

    Anno Siegel Guest

    Bigus <> wrote in comp.lang.perl.misc:
    > I'm not sure what this method is called, which is perhaps why I've had no
    > luck when searching around the web for info on it, but when you want a
    > 1-line alternative to an if...else.. construct, you can use the following
    > syntax:
    >
    > $ctr > 3 ? $text = "yes" : $text = "no";
    >
    > that works fine, however, when I try this:
    >
    > my $incsubs;
    > $line =~ /\ts/i ? $incsubs = 0 : $incsubs = 1;
    >
    > it doesn't work.. well, $incsubs equals 1 regardless whereas it works in the
    > standard if...else.. construct.
    >
    > I guess this is because the regular expression doesn't return true/false, or
    > sth like that.. is there a "trick" you can use to make this type of method
    > work with regexps?


    Wrong diagnosis. A regex returns a boolean value in scalar context,
    that part of your expression is quite all right.

    Your problem is one of precedence. Perl parses your expression like
    this:

    ( ( $line =~ /\ts/i) ? ( $incsubs = 0) : $incsubs) = 1;

    So if you have a match, $incsubs is set to 0 and $incsubs is returned.
    If you don't have a match, $incsubs is not set to 0, but returned as is.
    In either case what is returned is $incsubs, and 1 is assigned to it
    unconditionally. Hence the result you see.

    Generally, the "?:" construct (sometimes called "ternary conditional",
    btw) should not be used for operations that have a side effect, like
    the assignments you are doing. Use a normal if/else for that, even if
    it's a bit longer.

    Using "?:", your conditional assignment can be written:

    my $incsubs = $line =~ /\ts/i ? 0 : 1;

    Now the assignment is outside the "?:". But now it becomes apparent
    that this is (almost) equivalent to

    my $incsubs = $line !~ /\ts/i;

    which is what I would use.

    Anno
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
    Anno Siegel, Jul 28, 2005
    #2
    1. Advertising

  3. Bigus

    Bigus Guest

    "Anno Siegel" <-berlin.de> wrote in message
    news:dcaenn$d40$-Berlin.DE...
    > Bigus <> wrote in comp.lang.perl.misc:

    [..]>> my $incsubs;
    >> $line =~ /\ts/i ? $incsubs = 0 : $incsubs = 1;
    >>

    [..]
    > Your problem is one of precedence. Perl parses your expression like
    > this:
    >
    > ( ( $line =~ /\ts/i) ? ( $incsubs = 0) : $incsubs) = 1;
    >
    > So if you have a match, $incsubs is set to 0 and $incsubs is returned.
    > If you don't have a match, $incsubs is not set to 0, but returned as is.
    > In either case what is returned is $incsubs, and 1 is assigned to it
    > unconditionally. Hence the result you see.


    Ahhh, so this would work:

    my $incsubs;
    $line =~ /\ts/i ? ($incsubs = 0) : ($incsubs = 1);

    > Generally, the "?:" construct (sometimes called "ternary conditional",
    > btw) should not be used for operations that have a side effect, like
    > the assignments you are doing. Use a normal if/else for that, even if
    > it's a bit longer.
    >
    > Using "?:", your conditional assignment can be written:
    >
    > my $incsubs = $line =~ /\ts/i ? 0 : 1;
    >
    > Now the assignment is outside the "?:". But now it becomes apparent
    > that this is (almost) equivalent to
    >
    > my $incsubs = $line !~ /\ts/i;


    OK, that sounds good. I 'll use that in this case. The previous syntax would
    be useful in situations where I want to make a non boolean assigment
    resulting from a regexp match.

    Thanks

    Bigus
    Bigus, Jul 28, 2005
    #3
  4. Bigus

    Ian Wilson Guest

    Bigus wrote:
    > when you want a
    > 1-line alternative to an if...else.. construct,


    Whilst I quite like
    $this = condition ? "foo" : "bar";

    What's so horrible about
    if (condition) {$this="foo";} else {$this="bar"}
    which I find quite readable?
    Ian Wilson, Jul 29, 2005
    #4
  5. Bigus

    Juha Laiho Guest

    "Bigus" <> said:
    >"Anno Siegel" <-berlin.de> wrote in message
    >news:dcaenn$d40$-Berlin.DE...
    >my $incsubs;
    >$line =~ /\ts/i ? ($incsubs = 0) : ($incsubs = 1);
    >
    >> Generally, the "?:" construct (sometimes called "ternary conditional",
    >> btw) should not be used for operations that have a side effect, like
    >> the assignments you are doing. Use a normal if/else for that, even if
    >> it's a bit longer.
    >>
    >> Using "?:", your conditional assignment can be written:
    >>
    >> my $incsubs = $line =~ /\ts/i ? 0 : 1;
    >>
    >> Now the assignment is outside the "?:". But now it becomes apparent
    >> that this is (almost) equivalent to
    >>
    >> my $incsubs = $line !~ /\ts/i;

    >
    >OK, that sounds good. I 'll use that in this case. The previous syntax would
    >be useful in situations where I want to make a non boolean assigment
    >resulting from a regexp match.


    Hmm.. somewhat yes; a non-boolean assignment based on whether a regexp
    did match or not. But then, if you assign constant values, you're after
    all assigning "a form of boolean" (that is, after the operation the
    variable will have one of two possible values, and later on something
    will depend on which of the two values was assigned).

    So, cases where you really have a use for this shorthand are not that
    common (esp. given the overall syntactic flexibility of perl), and
    when you finally have a case complex enough to warrant this, it might
    be at the same time complex enough to warrant a full-blown conditional
    construct.
    --
    Wolf a.k.a. Juha Laiho Espoo, Finland
    (GC 3.0) GIT d- s+: a C++ ULSH++++$ P++@ L+++ E- W+$@ N++ !K w !O !M V
    PS(+) PE Y+ PGP(+) t- 5 !X R !tv b+ !DI D G e+ h---- r+++ y++++
    "...cancel my subscription to the resurrection!" (Jim Morrison)
    Juha Laiho, Jul 29, 2005
    #5
  6. Bigus

    Paul Lalli Guest

    Ian Wilson wrote:
    > Bigus wrote:
    > > when you want a
    > > 1-line alternative to an if...else.. construct,

    >
    > Whilst I quite like
    > $this = condition ? "foo" : "bar";
    >
    > What's so horrible about
    > if (condition) {$this="foo";} else {$this="bar"}
    > which I find quite readable?


    For one thing, it takes even longer if you are properly scoping your
    variables (and this is the first instance of the variable:

    my $this = condition() ? 'foo' : 'bar';
    # vs...
    my $this;
    if (condition()) { $this = 'foo' } else { $this = 'bar' }

    It's not so much a matter of readabilty, it's a matter of conciseness.
    For me anyway.

    The former tells you straight out that $this is going to be one thing
    or another based on condition(). The latter only tells you that
    something or something else will happen based on condition(), and you
    have to visually scan the remainder of the block to know that the two
    options are the possible values of a single variable.

    Paul Lalli
    Paul Lalli, Jul 29, 2005
    #6
  7. On Fri, 29 Jul 2005 10:04:54 +0000 (UTC)
    Ian Wilson <> wrote:

    > Bigus wrote:
    > > when you want a
    > > 1-line alternative to an if...else.. construct,

    >
    > Whilst I quite like
    > $this = condition ? "foo" : "bar";
    >
    > What's so horrible about
    > if (condition) {$this="foo";} else {$this="bar"}
    > which I find quite readable?
    >


    The ternary operator looks wonderfully geeky ;-). But I agree with you, you should use if ... else for more sophisticated conditionals, for your own sake and your co-workers'.
    Sven-Thorsten Fahrbach, Jul 29, 2005
    #7
  8. Ian Wilson <> wrote:
    > Bigus wrote:
    >> when you want a
    >> 1-line alternative to an if...else.. construct,

    >
    > Whilst I quite like
    > $this = condition ? "foo" : "bar";
    >
    > What's so horrible about



    "horrible" is prejudicial, putting the question in a more reasoned manner:

    Why prefer it over


    > if (condition) {$this="foo";} else {$this="bar"}



    As with most style issues, the choice should be based on clearly
    communicating the code's intent.

    A commonly accepted style-choice here is to use the 1st for a
    conditional _value_ and the 2nd for conditional flow control.

    So the 1st would be preferred _here_, because ?: (should) always means
    "select a value", while you have to analyse the 2nd only to come
    to what would be a foregone conclusion if the 1st had been used instead.


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Jul 29, 2005
    #8
  9. On Fri, 29 Jul 2005 08:42:32 -0500
    Tad McClellan <> wrote:

    > As with most style issues, the choice should be based on clearly
    > communicating the code's intent.
    >
    > A commonly accepted style-choice here is to use the 1st for a
    > conditional _value_ and the 2nd for conditional flow control.
    >
    > So the 1st would be preferred _here_, because ?: (should) always means
    > "select a value", while you have to analyse the 2nd only to come
    > to what would be a foregone conclusion if the 1st had been used instead.


    Good point. I think a good illustration is the following code:

    printf ("\$foo is %s.\n", $foo ? "true" : "false");

    This is (in my opinion) even more concise than:

    if ($foo) {
    print "\$foo is true.\n";
    }
    else {
    print "\$foo is false.\n";
    }

    You shouldn't use the ternary operator if you're dealing with something like:

    if (($condition1) && ($value1 == $value2) && (! $condition2)) {
    # long piece of code
    }
    else {
    # another long piece of code
    }

    This may sound trivial though, I think one should rely on common sense as when to use the two conditionals.
    Sven-Thorsten Fahrbach, Jul 29, 2005
    #9
  10. Bigus

    Guest

    Ian Wilson <> wrote:
    > Bigus wrote:
    > > when you want a
    > > 1-line alternative to an if...else.. construct,

    >
    > Whilst I quite like
    > $this = condition ? "foo" : "bar";
    >
    > What's so horrible about
    > if (condition) {$this="foo";} else {$this="bar"}
    > which I find quite readable?


    Where do you put the "my"?

    Xho

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
    , Jul 29, 2005
    #10
  11. Ian Wilson wrote:
    > Bigus wrote:
    >
    >> when you want a
    >> 1-line alternative to an if...else.. construct,

    >
    >
    > Whilst I quite like
    > $this = condition ? "foo" : "bar";
    >
    > What's so horrible about
    > if (condition) {$this="foo";} else {$this="bar"}
    > which I find quite readable?


    For one thing, you can't use it as an alternative to:

    my $this = condition ? "foo" : "bar";

    And it is more economical in a case like:

    $x[$i + $j - 1] = condition ? "foo" : "bar";

    --
    John W. Kennedy
    "I want everybody to be smart. As smart as they can be. A world of
    ignorant people is too dangerous to live in."
    -- Garson Kanin. "Born Yesterday"
    John W. Kennedy, Jul 30, 2005
    #11
  12. John W. Kennedy wrote:
    > Ian Wilson wrote:
    >> Bigus wrote:
    >>
    >>> when you want a
    >>> 1-line alternative to an if...else.. construct,

    >>
    >>
    >> Whilst I quite like
    >> $this = condition ? "foo" : "bar";
    >>
    >> What's so horrible about
    >> if (condition) {$this="foo";} else {$this="bar"}
    >> which I find quite readable?

    >
    > For one thing, you can't use it as an alternative to:
    >
    > my $this = condition ? "foo" : "bar";
    >
    > And it is more economical in a case like:
    >
    > $x[$i + $j - 1] = condition ? "foo" : "bar";


    And don't forget you can use it as an lvalue as in:

    ( condition ? $foo : $bar ) = $this;

    Or:

    push @{ condition ? \@foo : \@bar }, $this;



    John
    --
    use Perl;
    program
    fulfillment
    John W. Krahn, Jul 30, 2005
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Siemel Naran

    Does true ^ true return false?

    Siemel Naran, Jun 17, 2004, in forum: C++
    Replies:
    19
    Views:
    643
    Chris Theis
    Jun 18, 2004
  2. Pierre Quentel

    "0 in [True,False]" returns True

    Pierre Quentel, Dec 12, 2005, in forum: Python
    Replies:
    59
    Views:
    1,004
    Grant Edwards
    Dec 16, 2005
  3. André
    Replies:
    3
    Views:
    1,554
  4. bdb112
    Replies:
    45
    Views:
    1,297
    jazbees
    Apr 29, 2009
  5. Shea Martin

    false or true == true .... WTF?

    Shea Martin, Apr 5, 2007, in forum: Ruby
    Replies:
    4
    Views:
    93
    Bertram Scharpf
    Apr 5, 2007
Loading...

Share This Page