is a2p fibbing ..(($.-$FNRbase)) 
Author Message
 is a2p fibbing ..(($.-$FNRbase))

Being a rank neophyte I'm tackling perl but often compare awk type
syntax since I know a little of awk already.

Looking for a operator that does the same job as awks' FNR.
(Keep track of line numbers relative to each input file)

I got this notation by running a2p against this awk code.

BEGIN {
        print FNR
        print NR
        print RS
        print FS
        print FILENAME

Quote:
}

Gave me:
   [...]
   print (($.-$FNRbase));
   print $.;
   print $/;
   print $FS;
   print $ARGV;

All of them except the first, work as advertised, but with that one I
just get the overall line count still.

This little test script:
cat test_lineno.pl
   #!/usr/bin/perl
   while (<>)
   {
      print (($.-$FNRbase)) . "\n";
   }
========================================
Against these files:

 $ wc -l test.d test.d2
      3 test.d
      4 test.d2
      7 total

$ ./test_lineno.pl  test.d test.d2
1234567

Just overall count shows up and something in the syntax is leaving out
the newline too.



Thu, 15 Jul 2004 17:38:11 GMT  
 is a2p fibbing ..(($.-$FNRbase))

Quote:

> All of them except the first, work as advertised, but with that one I
> just get the overall line count still.

> This little test script:
> cat test_lineno.pl
>    #!/usr/bin/perl
>    while (<>)
>    {
>       print (($.-$FNRbase)) . "\n";
>    }
> ========================================
> Against these files:

>  $ wc -l test.d test.d2
>       3 test.d
>       4 test.d2
>       7 total

> $ ./test_lineno.pl  test.d test.d2
> 1234567

> Just overall count shows up and something in the syntax is leaving out
> the newline too.

If you take a look at 'perldoc perlvar' and search for $., there's a
note that when you're using the while (<>) idiom, line numbers
increase across ARGV files, and it points you towards some examples
in the perlfunc manpage.

Adapting those examples (and fixing a small bug), your test script
could be

#!/usr/bin/perl -w

$FNRbase = 0;
while (<>)
{
    print $.-$FNRbase,"\n";

Quote:
} continue {

    $FNRbase = $. if eof;

Quote:
}

--
Brian Palmer
"Whoever fights monsters should see to it that in the process he does
not become a monster. And when you look long into an abyss, the abyss
also looks into you"  - Nietzsche


Fri, 16 Jul 2004 00:06:06 GMT  
 is a2p fibbing ..(($.-$FNRbase))

Quote:

> Being a rank neophyte I'm tackling perl but often compare awk type
> syntax since I know a little of awk already.

> Looking for a operator that does the same job as awks' FNR.
> (Keep track of line numbers relative to each input file)

> I got this notation by running a2p against this awk code.

> BEGIN {
>         print FNR
>         print NR
>         print RS
>         print FS
>         print FILENAME
> }

Accessing the variables FNR, NR, and FILENAME in a BEGIN rule (i.e.,
prior to opening and reading any files) makes no sense. You can't
expect a2p to Do The Right Thing with a senseless awk script.

- Show quoted text -

Quote:
> Gave me:
>    [...]
>    print (($.-$FNRbase));
>    print $.;
>    print $/;
>    print $FS;
>    print $ARGV;

> All of them except the first, work as advertised, but with that one I
> just get the overall line count still.

> This little test script:
> cat test_lineno.pl
>    #!/usr/bin/perl
>    while (<>)
>    {
>       print (($.-$FNRbase)) . "\n";
>    }
> ========================================
> Against these files:

>  $ wc -l test.d test.d2
>       3 test.d
>       4 test.d2
>       7 total

> $ ./test_lineno.pl  test.d test.d2
> 1234567

> Just overall count shows up and something in the syntax is leaving out
> the newline too.

Because $FNRbase isn't special. It's a user variable that's
initialized to 0. So in your script named test_lineno.pl (which,
by the way, is *not* the output of a2p),

    ($. - $FNRbase) == ($. - 0) == $.

Fix the awk script and observe what happens to the resultant
a2p-generated Perl script:

$ cat test.awk
{
    print FNR
    print NR
    print RS
    print FS
    print FILENAME

Quote:
}

$ a2p test.awk
#!perl

[...]

$FS = ' ';              # set field separator
$, = ' ';               # set output field separator
$\ = "\n";            # set output record separator

while (<>) {
    chomp;      # strip record separator

    print (($.-$FNRbase));
    print $.;
    print $/;
    print $FS;
    print $ARGV;

Quote:
}

continue {
    $FNRbase = $. if eof;
Quote:
}

$

Notice that $FNRbase gets reset to the value of $. at the end of
each file. That's the trick.

This is a good illustration of why it's a Bad Idea to try to learn
Perl by shoveling old awk scripts through a2p. It's useful for
occasional hints, but it writes lousy tutorials.

By the way, here's the standard convention for resetting $. to the
number of the current line of the file being read using the null
filehandle:

while (<>) {
    ...

Quote:
} continue {

    close ARGV if eof;

Quote:
}

See perldoc perlvar and perldoc perlfunc.


Fri, 16 Jul 2004 01:53:28 GMT  
 is a2p fibbing ..(($.-$FNRbase))

Quote:

> $FNRbase = 0;
> while (<>)
> {
>     print $.-$FNRbase,"\n";
> } continue {
>     $FNRbase = $. if eof;
> }

Thanks Brian.  And for the pointer too.  I did know the part about
`$.' increasing over all files input, but I don't think I would have
ever spotted the little note you mentioned and it provides a nifty
little code snippet that does the job by commenting one line.

      while (<>) {
      #    next if /^\s*#/;        # skip comments
          print "$.\t$_";
      } continue {
          close ARGV  if eof;     # Not eof()!
      }

Both your code and the example from perlfunc do the job, but I'll
confess I don't really follow the action in either code snippet.

The one above references ARGV with no $ or ARGV[N] thats pretty
different than what I've been seeing in my studies.

Yours looks like its saying:
   print ($_ - 0),"\n"
So that zero gets subtracted from the line number until the second
file is opened then $FNRbase is reset to 1 at the end of each file
there after.

What is the significance of subtracting zero from $_?  Is there some
pitfall to just setting it to 1 straight away?

This little exercise started me experimenting and I came up with
another way, proving the perl axiom I guess.  But I wonder if there
are hidden problems with it that my noob eyes are missing.

   $cnt = 1;
   while (<>)
   {  chomp;
      print "Relative:<" . $cnt++ . "> File:<$ARGV> Overall:<$.>\n";
      $cnt = 1 if eof; next;
   }



Fri, 16 Jul 2004 04:48:59 GMT  
 is a2p fibbing ..(($.-$FNRbase))

Quote:

> Thanks Brian.  And for the pointer too.  I did know the part about
> `$.' increasing over all files input, but I don't think I would have
> ever spotted the little note you mentioned and it provides a nifty
> little code snippet that does the job by commenting one line.
> Both your code and the example from perlfunc do the job, but I'll
> confess I don't really follow the action in either code snippet.

I adapted the example to make it closer to your snippet; the perlfunc
example is probably the better way of doing the job.

Quote:

> The one above references ARGV with no $ or ARGV[N] thats pretty
> different than what I've been seeing in my studies.

That's a file handle; it's just like one you open by doing
        open MYFILE,"< file" or die("Unable to open file: $!");
        # ...
        close MYFILE;

Quote:
> Yours looks like its saying:
>    print ($_ - 0),"\n"
> So that zero gets subtracted from the line number until the second
> file is opened then $FNRbase is reset to 1 at the end of each file
> there after.

Not quite. I wrote
   print $.-$FNRbase,"\n";
(note $. rather than $_, but I assume that was a typo).
When done with the first file, $FNRbase is set to the current line
number; the loop happens,and $. is incremented again. Thus,each file
begins at line 1, as $. is always the line immediately before the
first line of the file.

Note that parenthesis at the beginning of the print arguments confuse
perl; you should pretty much always run your code via 'perl -w', so
that you get warned about that sort of situation.  You don't need any
parenthesis in this case

Quote:
> This little exercise started me experimenting and I came up with
> another way, proving the perl axiom I guess.  But I wonder if there
> are hidden problems with it that my noob eyes are missing.

>    $cnt = 1;
>    while (<>)
>    {  chomp;
>       print "Relative:<" . $cnt++ . "> File:<$ARGV> Overall:<$.>\n";
>       $cnt = 1 if eof; next;
>    }

The 'chomp' and 'next' there are unneeded.

--
Brian Palmer
"Whoever fights monsters should see to it that in the process he does
not become a monster. And when you look long into an abyss, the abyss
also looks into you"  - Nietzsche



Fri, 16 Jul 2004 12:16:05 GMT  
 is a2p fibbing ..(($.-$FNRbase))

Quote:

> Notice that $FNRbase gets reset to the value of $. at the end of
> each file. That's the trick.

OK, that clicks.  We get to end of file and that triggers the
`continue' block which resets $FNRbase to $. so that by subtracting
we get a fresh start on the next file. (a dim light comes on)

Quote:
> This is a good illustration of why it's a Bad Idea to try to learn
> Perl by shoveling old awk scripts through a2p. It's useful for
> occasional hints, but it writes lousy tutorials.

Actually I think this particular case doesn't really bare out that
claim because as you said it was a dopey awk snippet I ran.  Just the
first thing that came to mind and wasn't ever real or from a real
script.  But as you showed, if given half a fighting chance a2p came
thru with enough to see exactly how it works.

Maybe not a tutorial but definitely a front runner for quick help for
noobs.  Before your post I sent another rendition of a way to get the
info ..probably has some unseen bad side.



Fri, 16 Jul 2004 12:52:06 GMT  
 is a2p fibbing ..(($.-$FNRbase))

Quote:


>> Thanks Brian.  And for the pointer too.  I did know the part about
>> `$.' increasing over all files input, but I don't think I would have
>> ever spotted the little note you mentioned and it provides a nifty
>> little code snippet that does the job by commenting one line.

>> Both your code and the example from perlfunc do the job, but I'll
>> confess I don't really follow the action in either code snippet.

> I adapted the example to make it closer to your snippet; the perlfunc
> example is probably the better way of doing the job.

It turnout both notations show enough to figure out what is
happening. I just dropped the ball about the subtraction part.  

Subtracting zero leaves the actual count on the first file as needed
Subtracting that total from the next file brings us back to 1.  I
always see red when any kind of even tiny math crops up...duh

Quote:
>> The one above references ARGV with no $ or ARGV[N] thats pretty
>> different than what I've been seeing in my studies.
> That's a file handle; it's just like one you open by doing
>         open MYFILE,"< file" or die("Unable to open file: $!");
>         # ...
>         close MYFILE;

Gack... should have spotted that... but really haven't dealt with file
handles much yet.

Quote:
> Note that parenthesis at the beginning of the print arguments confuse
> perl; you should pretty much always run your code via 'perl -w', so
> that you get warned about that sort of situation.  You don't need any
> parenthesis in this case

Thanks for the tip about parens.  It is confusing knowing when to use
them or not.  Fortuneately for me perl is pretty forgiving about that.

Quote:

>> This little exercise started me experimenting and I came up with
>> another way, proving the perl axiom I guess.  But I wonder if there
>> are hidden problems with it that my noob eyes are missing.

>>    $cnt = 1;
>>    while (<>)
>>    {  chomp;
>>       print "Relative:<" . $cnt++ . "> File:<$ARGV> Overall:<$.>\n";
>>       $cnt = 1 if eof; next;
>>    }

> The 'chomp' and 'next' there are unneeded.

Oh, I see what happened.. originally I was printing the count followed
by the actual content of the line:

print "Relative:<" . $cnt++ . "> File:<$ARGV> Overall:<$.> Line:<$_>\n";

That caused the trailing bracket to appear on a newline because of the
newline contained in $_.  I just carried over after deciding the line
content wasn't doing anything for posting purposes and editing it out.
Neglecting to notice that the chomp was then unnecessary.

But I can't think of a good lie to cover `next'...

So removing those two things makes the statement even shorter..thanks.



Fri, 16 Jul 2004 23:31:58 GMT  
 
 [ 7 post ] 

 Relevant Pages 

1. Querying field information in Access2k/Delphi

2. Paradox 7 Can I make Executable Files

3. D1 Q: Determining before and after values when user changes DBGRID field?

4. Delphi vs. Access

5. Please Helpppp <---------------

6. memofields in delphi3 with IBM DB2

7. DOS 132x50 Text Mode problem.

8. PROBLEM WITH IMPORTING DBF FILES

9. Thread und Stored-Procedure

10. Compile to Windows?

11. DOCS NEEDED

12. "Vendor initialization failed..."

 

 
Powered by phpBB® Forum Software