Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Re: State information for flipflop .. operator.

by pbeckingham (Parson)
on Aug 16, 2004 at 14:07 UTC ( [id://383299]=note: print w/replies, xml ) Need Help??


in reply to State information for flipflop .. operator.

It's a strange, but nice operator isn't it?

If you have looping that uses while (<>) then you have other reentrancy issues, and so you would need to rework that to use lexical file handles.

The .. operator does actually return $., (shameless plug: check The Scalar Range Operator for a brief discussion on what the operator returns) so you do stand a chance of being able to save and restore state yourself, but would need to skip already-processed input yourself by reading up until $.. I don't think your task is an easy one.



pbeckingham - typist, perishable vertebrate.

Replies are listed 'Best First'.
Re^2: State information for flipflop .. operator.
by Fiftyvolts (Novice) on Aug 16, 2004 at 19:53 UTC

    Maybe I'm misunderstanding you and maybe I'm wrong, but as far as I know .. doesn't return $. -- for example:

    my @letters = qw(a b c d e); #'a'..'e' also works, #but I didn't want to add #a red herring ;-) print ' $_ | $r | $.'."\n"; for (@letters) { if(my $r = /a/../e/) { printf "%4s |%4s |%4s\n", $_, $r, $.; } $.++; # ok, this is silly # but I'm making a point ;-) }

    The output is the following:

    $_ | $r | $. a | 1 | b | 2 | 1 c | 3 | 2 d | 4 | 3 e | 5E0 | 4

    You're thread is pretty infomative, perhaps you meant something other than you wrote?

    ---- The super-user prompt is set to # to remind users of its awesome power.

      Well, no, I meant what I said. $. while reading a file is different from the zero-based array index. Here is your code now reading from __DATA__:

      #! /usr/bin/perl -w use strict; my @letters = qw(a b c d e); #'a'..'e' also works, #but I didn't want to add #a red herring ;-) print ' $_ | $r | $.'."\n"; for (@letters) { if(my $r = /a/../e/) { printf "%4s |%4s |%4s\n", $_, $r, $.; } $.++; # ok, this is silly # but I'm making a point ;-) } print "\n", ' $_ | $r | $.'."\n"; while (<DATA>) { chomp; if(my $r = /a/../e/) { printf "%4s |%4s |%4s\n", $_, $r, $.; } } __DATA__ a b c d e
      And the output is (hey - use strict found an error):
      $_ | $r | $. Use of uninitialized value in printf at ./r2.pl line 12. a | 1 | b | 2 | 1 c | 3 | 2 d | 4 | 3 e | 5E0 | 4 $_ | $r | $. a | 1 | 1 b | 2 | 2 c | 3 | 3 d | 4 | 4 e | 5E0 | 5



      pbeckingham - typist, perishable vertebrate.

        The error is from using warnings not strict ;)

        I'm still a little confused about what you mean. Are you just saying that the first line of a file is "line 1" rather than "line 0" as someone might expect because there are 0 based arrays? Yeah totally, that is correct. Your use of a special variable confused me :) The rest of this node is just a digression and can be ignored if you want :D

        I don't think it's really fair to say $. has anything to do with the return value of the .. operator. As I understand it $. contains data from a memory location associated with the last read file handle, and is incremented every time you use <>. Since $. is not just a copy of the line number, but actually is the data stored you can create things like the following ugliness:


        my $output='$std | dot |$data| dot '."\n"; while(<>) { my $std = $_; my $std_dot = $.; my $data = <DATA>; my $data_dot = $.++; chomp $std; chomp $data; last if $std eq '.'; $output.=sprintf "%4s |%4s |%4s |%4s\n", $std, $std_dot, $data, $data_dot; } print $output; __DATA__ a b c d e

        And this has the following input/output:


        a b c d e . $std | dot |$data| dot a | 1 | a | 1 b | 2 | b | 3 c | 3 | c | 5 d | 4 | d | 7 e | 5 | e | 9

        I highly doubt that would be useful, but it's interesting to point out how $. is saved. Now, to incorperate the .. operator:


        my $output='$std | dot | $r1 |$data| dot | $r2 '."\n"; while(<>) { my $std = $_; my $std_dot = $.; my $data = <DATA>; my $data_dot = $.++; chomp $std; chomp $data; my ($r1, $r2); if( ($r1 = $data =~ /a/ .. $data =~ /e/) && ($r2 = $std =~ /a/ .. $std =~ /e/) ) { $output.=sprintf "%4s |%4s |%4s |%4s |%4s |%4s \n", $std, $std_dot, $r1, $data, $data_dot, $r2; } else { last; } } print $output; __DATA__ a b c d e

        This takes/yields the following:


        a b c d e f $std | dot | $r1 |$data| dot | $r2 a | 1 | 1 | a | 1 | 1 b | 2 | 2 | b | 3 | 2 c | 3 | 3 | c | 5 | 3 d | 4 | 4 | d | 7 | 4 e | 5 | 5E0 | e | 9 | 5E0

        It seems pretty clear that the .. operator uses some kind of internal counter. I know, I'm totally abusing the $. variable in these examples. My question is where does the value of $. go if you use it without the <> operator.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://383299]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (5)
As of 2024-03-28 14:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found