Skip to content

Instantly share code, notes, and snippets.

Created November 21, 2016 19:38

Revisions

  1. @invalid-email-address Anonymous created this gist Nov 21, 2016.
    58 changes: 58 additions & 0 deletions gistfile1.txt
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,58 @@

    Line limit counting problem in $*ARGFILES.lines method

    When passing a line count argument to the .lines method, it mis-counts the lines

    For the examples, consider this input file:

    $ cat file
    A
    B

    Examples:

    perl6 -e 'say $*ARGFILES.lines' file file #=> (A B A B)
    perl6 -e 'say $*ARGFILES.lines(1)' file file #=> (A)
    perl6 -e 'say $*ARGFILES.lines(2)' file file #=> (A B)
    perl6 -e 'say $*ARGFILES.lines(3)' file file #=> (A B) <-- WRONG
    perl6 -e 'say $*ARGFILES.lines(4)' file file #=> (A B A) <-- WRONG

    say IO::ArgFiles.new(:args(<file file>.Array)).lines #=> (A B A B)
    say IO::ArgFiles.new(:args(<file file>.Array)).lines(1) #=> (A)
    say IO::ArgFiles.new(:args(<file file>.Array)).lines(2) #=> (A B)
    say IO::ArgFiles.new(:args(<file file>.Array)).lines(3) #=> (A B) <-- WRONG
    say IO::ArgFiles.new(:args(<file file>.Array)).lines(4) #=> (A B A) <-- WRONG

    Inserting /dev/null in the middle of the argument list to illustrate the problem

    perl6 -e 'say $*ARGFILES.lines(5)' file /dev/null file #=> (A B A)

    say IO::ArgFiles.new(:args(<file /dev/null file>.Array)).lines(5) #=> (A B A)

    $*ARGFILES is created from IO::ArgFiles.new(:args(@*ARGS))
    I think the problem is inside the method lines($limit=*) of the rakudo/src/core/IO/ArgFiles.pm file
    method pull-one of the Seq calls itself recursively when it reaches the end of a file
    $!limit should only be decremented when an actual line is returned

    Suggested fix:

    --- rakudo-2016.11/src/core/IO/ArgFiles.pm.orig 2016-11-21 16:56:02.843748043 -0200
    +++ rakudo-2016.11/src/core/IO/ArgFiles.pm 2016-11-21 16:56:24.508748604 -0200
    @@ -103,7 +103,7 @@
    }

    method pull-one() {
    - return IterationEnd if $!limit-- <= 0;
    + return IterationEnd if $!limit <= 0;
    my \value = $!iter.pull-one;
    if value =:= IterationEnd {
    my $io = $!next-io.();
    @@ -114,6 +114,7 @@
    }
    else {
    $!ins++;
    + $!limit--;
    value;
    }
    }