http://www.perlmonks.org?node_id=11119539

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

Hello, please dear Monks I'm using the Modern Perl Book to learn perl. I'm not getting this part
For example, the eq operator tests that two values contain equivalent +string values: say "Catastrophic crypto fail!" if $alice eq $bob;
What are the string values of $alice and $bob since they haven't been assigned anything before?
  • Comment on Learning Programming, desperately need to know what information is contained in scalar variables
  • Download Code

Replies are listed 'Best First'.
Re: Learning Programming, desperately need to know what information is contained in scalar variables
by choroba (Cardinal) on Jul 20, 2020 at 08:32 UTC
    If no value is assigned to a scalar variable, it contains undef.

    The example in the book doesn't want to show you what undef is, though. You should experiment with assigning various values to the variables and running the comparison, e.g.

    my $alice = 'Alice'; my $bob = 'Bob'; say "Catastrophic crypto fail!" if $alice eq $bob;

    and

    my $alice = 'bob'; my $bob = reverse $alice; say "Catastrophic crypto fail!" if $alice eq $bob;

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
      Thank you very, very, very much! <3

        ... the book doesn't want to show you what undef is... Actually it does. And probably choroba meant something different and I quoted him wrong. But I’m pretty sure that he doesn’t worry 🤪😎 Hint: Don’t just copy examples from this splendid book. Invent your own. Play and have fun. Good «trivial examples» are pure fun and hard to figure out... Best regards, Karl

        «The Crux of the Biscuit is the Apostrophe»

        perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help

Re: Learning Programming, desperately need to know what information is contained in scalar variables
by davido (Cardinal) on Jul 20, 2020 at 15:41 UTC

    If $alice and $bob were not assigned values, they are undef. Unlike a language such as C where using a variable that has never been assigned can result in undefined behavior, in Perl the behavior is predictable, and documented. undef is treated like an out-of-band value; it's neither a string nor a number, it's just undef. The undef value has several features:

    • Its presence can be tested or using defined, //, and //= (perlop).
    • If it is used somewhere that Perl expects to find a string, it will be upgraded for the duration of that operation to being an empty string.
    • If it is used somewhere that Perl expects to find a number, it will be upgraded for the duration of that operation to being equal to zero.
    • If it is used in Boolean context it is treated as false.
    • Numeric and string upgrades will trigger a warning in most cases if the warnings pragma is in effect.
    • These upgrades slightly modify the internal structure of what Perl stores in the container we know as a scalar. These modifications should not be of interest in "everyday" work, but can be observed with the Devel::Peek module.

    Here are some examples:

    use strict; use warnings; use Devel::Peek; { my $foo; print '$foo is ', (defined($foo) ? 'defined' : 'undef'), "\n"; Dump($foo); } print "\n\n"; { my $foo; print '$foo eq $foo: $foo is stringwise ', ($foo eq $foo ? 'equal' + : 'unequal'), "\n"; Dump($foo); } print "\n\n"; { my $foo; print '$foo == $foo: $foo is numerically ', ($foo == $foo ? 'equal +' : 'unequal'), "\n"; Dump($foo); }

    The output will look like this:

    $foo is undef SV = NULL(0x0) at 0x1275f40 REFCNT = 1 FLAGS = () Use of uninitialized value $foo in string eq at mytest.pl line 17. Use of uninitialized value $foo in string eq at mytest.pl line 17. $foo eq $foo: $foo is stringwise equal SV = PV(0x1252e70) at 0x12a0470 REFCNT = 1 FLAGS = () PV = 0 Use of uninitialized value $foo in numeric eq (==) at mytest.pl line 2 +4. Use of uninitialized value $foo in numeric eq (==) at mytest.pl line 2 +4. $foo == $foo: $foo is numerically equal SV = PVNV(0x12510f0) at 0x12a0608 REFCNT = 1 FLAGS = () IV = 0 NV = 0 PV = 0

    The first block tests for definedness, and then shows what's inside the scalar. Essentially it's empty, just contains undef.

    The second block tests the scalar for string equality. This will cause a PV (string value) to be added to the scalar's internal structure, but the PV is =; it's empty. A future test for definedness would still be true. Perl happily just treated undef values as empty strings and compared them. Notice that warnings were generated.

    The third block tests the scalar for numeric equality. This has caused an IV and NV (integer and numeric value) field to show up in the scalar struct. They are also empty. The PV field showed up again too, and is also empty. The scalar will still report to be undef if tested with defined. But internally its structure has been altered a little. Notice the warnings again, for doing a numeric comparison on uninitialized value.

    All this is hidden in the internals. Mostly you just have to keep in mind that if it hasn't been initialized it will be undef, and that Perl is willing to let you do string and numeric operations and comparisons on undef, upgrading to the appropriate datatype as needed.


    Dave

      I have the book Learning Perl in it there's a section called "Using Scalar-Producing Expressions in List Context" then it goes on to say "Going this direction is straightforward: if an expression doesn't normally have a list value, the scalar value is automatically promoted to make a one-element list:
      @fred = 6 * 7; #gets the one-element list (42) @barney = "hello" . '' . "world";
      In the first example, the array @fred on the left hand side of the operator = makes it a list context, did i got it right? In the second example, "hello" . '' . "world; alone is a scalar expression? Is the array @barney on the left hand side of the operator making it into list context like the first example?
        Yes

        @something = ... ;

        or

        (...) = ... ;

        Are "list assignments".

        The RHS (right hand side) is in list context and the resulting list will be unpacked into the LHS.

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

        FIX EDIT: Is the array @barney on the left hand side of the operator = making it into list context like the first example?
      That's awesome, thank you very much Dave. I have another question about this piece of code say "Catastrophic crypto fail!" if $alice eq $bob; what value is the expression $alice eq $bob producing?
        «...awesome...»

        Sure. It is the canonical answer. But now comes practice. Which is just another word for repetition. Remember: «No Intuition Without Repetition» (Dr Wisenheimer)

        «The Crux of the Biscuit is the Apostrophe»

        perl -MCrypt::CBC -E 'say Crypt::CBC->new(-key=>'kgb',-cipher=>"Blowfish")->decrypt_hex($ENV{KARL});'Help

        The expression $alice eq $bob is returning true because both $alice and $bob are undef, that's both contain the same information hence they are equal. Am I right?
Re: Learning Programming, desperately need to know what information is contained in scalar variables
by AnomalousMonk (Archbishop) on Jul 20, 2020 at 22:47 UTC