Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask

defined ? to be : not

by Don Coyote (Pilgrim)
on Jun 12, 2012 at 12:40 UTC ( #975767=perlmeditation: print w/replies, xml ) Need Help??

as always a couple of threads make sense when you join them together

In chat the subject of length of a defined scalar popped up, and discussions of if else conditional syntax have occured, this article merges parts of those ideas together

from the command line, this was being typed

shell$ perl -e 'my $input = <>; chomp($input);if (length($input)) { pr +int q(length) }; if (defined($input)) { print q(defined) };

with questions about why zero length scalars remain defined.

I quickly suggested that a true conditional be placed as a further argument, to suggest the reason. I went back to this after, and evolved a useful learning trick.

Briefly the code suggested in the title is obviously the famous shakespearian quote to be or not to be? Well more rightly it is the answer if Romeo makes the decision, the question itself is an OR conditionial, ok IM getting existential now...

if($decision eq "to be"){print "Romeo is"} else{print "Romeo is not"}

translates to

$dec eq "to be" ? print "Romeo is" : print "Romeo is not";

Best to start with the truth I think. In the original command line the input scalar will always be defined, as it is a scalar passed to the code via the command line. What it will or won't be is true. Lined out for readability.

shell$ perl -e 'my $input=<>; chomp $input; print q(Romeo ); $input ? print q(is ) : print q(is not ); print qq(\ntaking ),length($input),qq( hours to decide!\n);

So lets try this with an undefined scalar. No input from command line and hence no chomp also. We will aslo extended the conditional argument so that the false or 'else' side becomes a further conditional or 'elsif' side. Either way something very interesting happens.

shell$ perl -e 'my $input; # not yet defined print q(Romeo ); #test for the scalar to be not defined to be true !defined $input ? print q(undefined ) : $input ? print q(is ) : print q(is not ); print qq(\n taking ),length($input),qq( hours to decide!\n);

So the crux of the play is surely whether the love was ever defined in the first place?!


Replies are listed 'Best First'.
Re: defined ? to be : not
by tobyink (Abbot) on Jun 12, 2012 at 14:29 UTC

    The "to be or not to be" speech is from Hamlet, not Romeo & Juliet. The gist of the speech is about whether our protagonist ought to commit suicide.

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
      our protagonist

      Our protagonist? S'not mine, Is 'e yourn?

      Sorry :) That's just one of those phrases beloved of Eng. Lit. profs that simply makes no sense whatsoever.

      (And yes, I was just as literal & argumentative way back then as now. Though I doubt that the latter had much affect on my abysmal tallies in Eng. Lit., the former certainly did.

      Whilst I've always appreciated the beauty and nuance of "cold hearted orb that rules the night; removes the colours from our sight"; I still have a strong preference for the concise accuracy of "The Moon".)

      With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

      The start of some sanity?

        I must admit I'd be more comfortable with "my protagonist". I'm quite possessive of Hamlet, but was willing to at least share him.

        The hostname for my previous desktop machine is ophelia; the current one is ophelia2. My laptop is miranda (from The Tempest).

        perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: defined ? to be : not
by johngg (Abbot) on Jun 12, 2012 at 22:38 UTC

    translates to

    $dec eq "to be" ? print "Romeo is" : print "Romeo is not";
    I think it is better to translate that to

    print $dec eq 'to be' ? 'Romeo is' : 'Romeo is not';

    or even

    print 'Romeo is', $dec eq 'to be' ? '' : ' not';

    There is less repetition and less chance of running into precedence problems this way. Note that I use single quotes as there is no interpolation happening.



      Passing the syntactic if conditional as an argument to print certainly would help with compacting the code and avoiding precedence. For a moment I wasn't sure what would happen if once evaluating to true a zero length string was returned, but of course in a list context it would be discarded as a value.

      The initial translation was a straight forward syntactic representation of the if condition. This meditation is aimed at the learning rather than the learned. And as you will see very quickly after this presentation of syntax I do replace the print romeo statement prior to the if conditional. Though you did manage shave off a few more keystrokes

      In this meditation interpolation is a factor, as the code is being executed on the command line through the use of the perl command and -e flag. So using the q() operator certainly helps with syntax errors on the command line due to numerous single quotes.

      Just like to add here a couple more useful switches for perl commands.

      perl -we 'code'. Initiates warnings, but continues to run the code if it can

      Shell$ perl -we 'my $word = q(yey);print qq($sword\n);' prints to tty: Name "main::sword" used only once: possible typo at -e line 1. Use of uninitialized value $sword in Concatenation (.) or String at -e + line 1. Shell$ _

      perl -ce compiles the code without attempting to execute and returns compilation errors.

      Shell$ perl -ce 'my $word = q(yey)); print qq($word\n);' prints to tty: syntax error at -e line 1, near "q(yey))" -e had compilation errors $Shell _

      Both very useful debugging switches. Pointing out different possible errors. Use along with 'use strict;' which can also be typed as first statement in a one liner on the command line. When combined, you have a fairly robust debugging practice. On the other hand, not knowing your Hamlet from your Romeo & Juliet is just plain unforgivable.


Re: defined ? to be : not
by Anonymous Monk on Jun 12, 2012 at 14:32 UTC

    Minor note; that chomp ; isn't working.

    If you had used warnings, perl would have told you. You probably want chomp $input; instead.

Re: defined ? to be : not
by Anonymous Monk on Jun 12, 2012 at 13:08 UTC
Re: defined ? to be : not
by Don Coyote (Pilgrim) on Jun 12, 2012 at 17:14 UTC

    updated chomp $input line - thought chomp worked on $_ though. to be honest i barely ran this one through the command line, but yes even so should have either used the flag or placed use warnings as the first statement.

    as for shakespearo:

    • To fail or not to fail? you're pwnd by the question!
    • Romeo! Romeo! Where fail art thou Romeo?
    • The Twelth Fail
    • If music be the fail of love, play on.
    • A Fail! A Fail! My Kingdom for a Fail!
    • Et tu, Faile?
    • Much Ado About Failing

    sub fail{shift = $Coyote ? fail : &fail($Coyote)};
Re: defined ? to be : not
by Neighbour (Friar) on Jun 13, 2012 at 11:43 UTC
    I dunno, since 5.10, we're given this possibility:
    print 'Romeo ' . (($input // 'magic') eq 'to be' ? 'is' : 'is not') . +"\n";
    ..or, alternatively:
    print 'Romeo is' . (($input // 'magic') ne 'to be' ? ' not' : '') . "\ +n";
Re: defined ? to be : not
by bulk88 (Priest) on Jun 18, 2012 at 06:32 UTC
    Undef is a value, and one particular unique value, it is not a classification and it has nothing to do with bool/truth hood evaluation. Because its printable form is empty string, undef is false. In some systems, -1 is a "false" too (not in perl). Truthhood has to do with flow control. Undef is best used as a unique flag that can mean, error or no data, to separate empty string/0 from error or no data condition, 0 is valid data some times. Undef can't be stored to a file. Falsehood can be stored to a file.

      Undef .. and it has nothing to do with bool/truth hood evaluation...

      sorry, but you failed to get there :)

      By your own explanation undef evaluates to false in boolean contexts, so yes, it has to do with bool/truth hood evaluation -- and it most certainly can be stored to a file

      Using definedness for flow control is one reason why I felt it would be suitable to use in the ternary operator example. I have also seen this used in where the ternary queries if the value is a reference as the method expects and proceeds accordingly.

      An example of using undefinedness as a control flow can be seen in this node where I help a fellow monk with identifying and then filling initialised array indexes. Trying to edit HoAoA entries. This does not use ternary condition syntax.