Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

true/false condition - what am I doing wrong?

by ultranerds (Friar)
on Dec 08, 2011 at 14:10 UTC ( #942439=perlquestion: print w/ replies, xml ) Need Help??
ultranerds has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I'm trying to do a basic function that with set $redo bases on the value of $type (either "add" or "edit) ... this is the sample code:

my $type = "add"; my $redo; $type eq "add" ? $redo = "wiki_add2" : $redo = "wiki_edit2"; print "With type: $type, we could redo: $redo \n"; my $type = "edit"; my $redo; $type eq "add" ? $redo = "wiki_add2" : $redo = "wiki_edit2"; print "With type: $type, we could redo: $redo \n";


For some reason it always returns "wiki_edit2" ... what am I doing wrong?

TIA!

Andy

Comment on true/false condition - what am I doing wrong?
Download Code
Re: true/false condition - what am I doing wrong?
by Taulmarill (Deacon) on Dec 08, 2011 at 14:23 UTC
    The correct way to use the teary operator would be like this:
    $redo = $type eq "add" ? "wiki_add2" : "wiki_edit2";
    I would like to tell you what exactly happens, when perl executes your version. But to be honest i can't quite figure it out.

      Exactly! Taulmarill has pointed it out right. You are using a compound if statement without the appropriate syntax. Also, I notice in your code that you've declared the variables $type and $redo twice within the same lexical scope! You might like to change this.

      Thanks guys - duh I should have seen that one. Joys of trying to work when you have a stinking headache and cold

      Thanks!

      Andy
Re: true/false condition - what am I doing wrong?
by pvaldes (Chaplain) on Dec 08, 2011 at 14:26 UTC
    nothing
Re: true/false condition - what am I doing wrong?
by Anonymous Monk on Dec 08, 2011 at 14:28 UTC

    I believe that's the equivalent of $type eq "add" ? ($redo = "wiki_add2" : $redo) = "wiki_edit2"; where the chained ='s apply the last value to everything.

    In general, adding brackets to the false part will fix you right up.

    $type eq "add" ? $redo = "wiki_add2" : ($redo = "wiki_edit2");

    In this specific case, you want what Taulmarill posted to avoid repeating yourself on the "$redo =" part.

Re: true/false condition - what am I doing wrong?
by si_lence (Deacon) on Dec 08, 2011 at 14:30 UTC
    You can use a block construct to get this to work:
    my $type = "add"; my $redo; $type eq "add" ? {$redo = "wiki_add2"} : {$redo = "wiki_edit2"}; print "With type: $type, we could redo: $redo \n";
      Did you mean 'do' block? Because using your example I get the following warnings:
      Useless use of anonymous hash ({}) in void context at test.pl line 5. Useless use of anonymous hash ({}) in void context at test.pl line 5. Odd number of elements in anonymous hash at test.pl line 5.
Re: true/false condition - what am I doing wrong?
by Anonymous Monk on Dec 08, 2011 at 14:58 UTC

    B::Deparse!!!

    $ perl -MO=Deparse,-p junk (my $type = 'add'); my($redo); ((($type eq 'add') ? ($redo = 'wiki_add2') : $redo) = 'wiki_edit2'); print("With type: $type, we could redo: $redo \n"); junk syntax OK $ perl -MO=Deparse,-p junk | perltidy junk syntax OK ( my $type = 'add' ); my ($redo); ( ( ( $type eq 'add' ) ? ( $redo = 'wiki_add2' ) : $redo ) = 'wiki_edi +t2' ); print("With type: $type, we could redo: $redo \n");
Re: true/false condition - what am I doing wrong?
by Marshall (Prior) on Dec 08, 2011 at 15:30 UTC
    This is an abuse of the ternary operator.

    Normally in this situation, you want to choose between 3 choices, not two!

    Use the ternary operator to set a variable dependent upon a true/ false condition.
    A common use would be like this:
    ($today eq 'Monday') ? $firstDay =1 : $firstDay =0;

    That would be preferred over:
    $firstDay=0;
    $firstDay=1 if ($today eq 'Monday');

    Use if and if/elsif/else conditions for more complicated things.

    #!/usr/bin/perl -w use strict; decide ('add'); decide ('edit'); decide ('bad input nothing'); print "\n"; decide2 ('add'); decide2 ('edit'); decide2 ('bad input nothing'); sub decide { my $input = shift; print "invalid input\n" if ($input ne "add" and $input ne "edit"); print "doing an add\n" if $input eq "add"; print "doing an edit\n" if $input eq "edit"; } sub decide2 { my $input = shift; if ($input eq 'add') { print "the add code goes here\n"; } elsif ($input eq 'edit') { print "the edit code goes here\n"; } else { print "the invalid input code goes here\n"; } } __END__ doing an add doing an edit invalid input the add code goes here the edit code goes here the invalid input code goes here
      A common use would be like this:
      ($today eq 'Monday') ? $firstDay =1 : $firstDay =0;
      I have always thought the common use is
      $firstDay = $today eq 'Monday' ? 1 : 0;
        correct - tired this morning.. been pulling late nights on a db project...
        main point is that this is not the right place for 'edit' vs 'add'.

        Update: even more uses are possible:

        #!/usr/bin/perl -w use strict; sub is_name_valid { return $_[0]; #just a dummy } print "the name ",is_name_valid(0) ? "was" :"was not"," valid\n"; # the name was not valid print "the name ",is_name_valid(1) ? "was" :"was not"," valid\n"; # the name was valid

      The ternary operator is stackable. So for three choices, the following might be bearable:

      use strict; use warnings; for my $type ( qw(add edit nada) ) { my $redo = $type eq 'add' ? 'wiki_add2' : $type eq 'edit' ? 'wiki_edit2' : 'error'; print "$type -> $redo\n"; } __END__ add -> wiki_add2 edit -> wiki_edit2 nada -> error

      But as AM points out, the OP's task seems to call for a dispatch table.

Re: true/false condition - what am I doing wrong?
by tobyink (Abbot) on Dec 08, 2011 at 19:23 UTC

    I've always quite liked this idiom, which scales nicely when you've got lots of choices:

    my $type = "add"; my $redo = { add => "wiki_add2", edit => "wiki_edit2", delete => "wiki_remove3", }->{$type} || "wiki_noneoftheabove7"; print "With type: $type, we could redo: $redo \n";

    Also since Perl 5.10, we've had the given keyword. Unless you're targeting legacy releases of Perl, that's probably your best bet:

    my $type = "add"; my $redo; given ($type) { when ("add") { $redo = "wiki_add2" } when ("edit") { $redo = "wiki_edit2" } when ("remove") { log("REMOVE") and $redo = "wiki_remove2" } default { $redo = "wiki_noneoftheabove7" } } print "With type: $type, we could redo: $redo \n";

    In Perl 5.12 onwards, when can be used as a (postfix) statement modifier:

    my $type = "add"; my $redo; given ($type) { $redo = "wiki_add2" when "add"; $redo = "wiki_edit2" when "edit"; when ("remove") { log("REMOVE") and $redo = "wiki_remove2" } default { $redo = "wiki_noneoftheabove7" } } print "With type: $type, we could redo: $redo \n";

    And from Perl 5.14, it gets even better, as given has a useful return value.

    my $type = "add"; my $redo = given ($type) { "wiki_add2" when "add"; "wiki_edit2" when "edit"; when ("remove") { log("REMOVE") and "wiki_remove2" } default { "wiki_noneoftheabove7" } }; print "With type: $type, we could redo: $redo \n";

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://942439]
Approved by toolic
Front-paged by ChuckularOne
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (17)
As of 2015-07-06 18:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (80 votes), past polls