Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

Is it a list or a flip-flop?

by TomDLux (Vicar)
on Aug 18, 2005 at 19:03 UTC ( [id://484933]=perlquestion: print w/replies, xml ) Need Help??

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

My team at work has started going over Damian's Perl Best Practices book, one item a day; we're starting with the Ten Esential Coding Practices summaries from Appendix A.

As a result, we're starting at the end of the book, pages 430-432: 'use strict', 'use warnings'.

We had a fun time going over the bit of code on page 430, trying to detect all the errors, and then reading the error messages, making sure we understood them all.

There's one I don't understand:

my $n = 9; my $list = (1..$n);

which reports an 'uninitialized value in range or flip'.

Please enlighten me, my brethren ... my forehead is flattening from pounding on the wall.

Update: I had identified the errror of attempting to assign a list to a scalar. Paladin wins the chocolate cigar, as proved by:

use strict; use warnings; my $n = 9; $. = 1 my $list = (1..$n); print "'$list'\n";

--
TTTATCGGTCGTTATATAGATGTTTGCA

Replies are listed 'Best First'.
Re: Is it a list or a flip-flop?
by Paladin (Vicar) on Aug 18, 2005 at 19:09 UTC
    You are using the .. operator in scalar context. When you do this, and have a number at one end, it compares that number to $. (the current line of the selected file handle, usually used in a while (<FH>) {} loop. Since you aren't reading a file, $. is uninitialized at this point.
Re: Is it a list or a flip-flop?
by Transient (Hermit) on Aug 18, 2005 at 19:10 UTC
    I'm going to go out on a limb here and suggest that perl is possibly trying to optimize this range in scalar context at compile time. Hence, it's not working.

    Compare to this - which does work:
    #!/usr/bin/perl use strict; use warnings; my $n = 9; my @list = (1..$n); my $list = @list; print @list, "\n"; print $list, "\n";


    Update: Limb broken - Paladin seems to have hit on it... as this will compile correctly as well:
    #!/usr/bin/perl use strict; use warnings; $. = 1; my $n = 9; my $list = (1..$n);


    Update2: From perlop:

    If either operand of scalar ".." is a constant expression, that operand is considered true if it is equal (== ) to the current input line number (the $. variable).

    Which means, this will also compile!
    #!/usr/bin/perl use strict; use warnings; my $m = 1; my $n = 9; my $list = ($m..$n);
    ... even with $. undefined.

      But what does $list contain? If I print it I get 1E0.


      Perl is Huffman encoded by design.
        From perlop:

        The value returned is either the empty string for false, or a sequence number (beginning with 1) for true. The sequence number is reset for each range encountered. The final sequence number in a range has the string "E0" appended to it, which doesn't affect its numeric value, but gives you something to search for if you want to exclude the endpoint. You can exclude the beginning point by waiting for the sequence number to be greater than 1.


        The range operator has always stumped me a bit, so I can't say much more than what it says above

        Update: I suppose it is working like this (in the case of setting $. to 1) - please correct me if I am wrong:

        Since 1 is a constant, and so is $., it is evaluated as TRUE.
        Since the LHS is true, the RHS is evaluated immediately.
        Since the RHS is NOT a constant, it is not compared to $., but is returned as true because it is not false (i.e. 9 is not 0, "" or undef).
        The range operation is completed.
        Because it is a single iteration only, the sequence number is 1, and is appended with "E0"
Re: Is it a list or a flip-flop?
by GrandFather (Saint) on Aug 18, 2005 at 19:10 UTC

    I'm not sure where the (or flip) comes from, but the problem is that the code is trying to assign a list to a scalar. Here are versions that work:

    use warnings; use strict; my $n = 9; my $listRef = [(1..$n)]; # Assign array reference my @list = (1..$n); # Assign to an array

    Perl is Huffman encoded by design.
Re: Is it a list or a flip-flop?
by revdiablo (Prior) on Aug 19, 2005 at 17:34 UTC

    Paladin has lucidly described the source of your error, but I notice there still seems to be some confusion about what the flip-flop operator actually does. Hopefully I can help clear the air a bit.

    It's probably best to think of scalar .. and list .. as two completely different operators. You can sort of kind of see a connection between them, but what they do is different enough that it's confusing to think of both at once. I assume we all know what list .. does; it's the scalar version that is kind of confusing. But when you shake yourself free from the baggage of thinking about the range operator, it becomes a lot easier to understand.

    The flip-flop is essentially a flag. It turns on, or off, depending on the two endpoints. The two endpoints are compared against something to determine whether or not to flip the flag on or off. If the first endpoint compares true, the flag is flipped on. If the second endpoint compares true, the flag is flipped off. This allows you to do some pretty useful things, such as get all the lines in a file between "BEGIN" and "END", or lines 2-24. Here are some (hopefully) clear examples:

    my @lines = qw(foo BEGIN bar baz END qux); for (@lines) { if (/BEGIN/ .. /END/) { print "$_\n"; } } while (<DATA>) { if (3 .. 5) { print; } } __DATA__ Line one Line two The third and fourth what about the fifth? or the sixth?
      Yes, in fact, flipflop will be a different operator in Perl 6, or maybe even just a macro. (A range operator in scalar context will just produce a range object.) And with the advent of state variables the macro could be written entirely in terms of lower-level primitives.
Re: Is it a list or a flip-flop?
by QM (Parson) on Aug 18, 2005 at 22:36 UTC
    I don't get an error at all if I add use diagnostics;.

    Also, one of my pet peeves is that Perl doesn't even try to tell you which entity is generating the uninitialized value. Sometimes it's not so easy to find (either because of code complexity, or sheer mental obstruction).

    -QM
    --
    Quantum Mechanics: The dreams stuff is made of

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (4)
As of 2024-04-23 18:11 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found