Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Calling .perl on an Match object produced by an inherited grammar fails with a Seq error #5124

Closed
p6rt opened this issue Feb 8, 2016 · 6 comments

Comments

@p6rt
Copy link

p6rt commented Feb 8, 2016

Migrated from rt.perl.org#127492 (status was 'resolved')

Searchable as RT127492$

@p6rt
Copy link
Author

p6rt commented Feb 8, 2016

From @sjn

Please inspect the attached example test.

The following error appears when calling .perl on the Match object returned by a subclassed JSON​::Tiny Grammar parser.

$ perl6 Match.perl-error.t
1..3
  ok 1 - myparse accepts proper JSON text
  ok 2 - Parsing result is a Match object
This Seq has already been iterated, and its values consumed
(you might solve this by adding .cache on usages of the Seq, or
by assigning the Seq into an array)
  in block <unit> at Match.perl-error.t line 28

@p6rt
Copy link
Author

p6rt commented Feb 8, 2016

From @sjn

# vim​: ft=perl6

use v6;
use JSON​::Tiny​::Grammar;
use JSON​::Tiny​::Actions;
use Test;

grammar A​::B​::Grammar is JSON​::Tiny​::Grammar { }
class A​::B​::Actions is JSON​::Tiny​::Actions { }

module A​::B {
  proto myparse ($) is export { * };
  multi myparse (Str​:D $json) {
  my $a = A​::B​::Actions.new;
  A​::B​::Grammar.parse( $json, :actions($a));
  }
}

import A​::B; # we need the &myparse sub

plan 3;

subtest {
  my $result = myparse $=finish; # Read from POD
  ok $result, 'myparse accepts proper JSON text';
  isa-ok $result, 'Match', 'Parsing result is a Match object';

  ok $result.perl, 'We can call .perl on the Match object';

  #note "##### Match.gist is " ~ $result.gist; # This works
  #note "##### Match.perl is " ~ $result.perl; # THIS FAILS

}, "Parse JSON file and print stuff";

=finish

{
  "name" : "JSON​::Tiny",
  "version" : "*",
  "description" : "A minimal JSON (de)serializer",
  "depends" : [ ],
  "provides" : {
  "JSON​::Tiny" : "lib/JSON/Tiny.pm",
  "JSON​::Tiny​::Actions" : "lib/JSON/Tiny/Actions.pm",
  "JSON​::Tiny​::Grammar" : "lib/JSON/Tiny/Grammar.pm"
  },
  "source-url" : "git​://github.com/moritz/json.git"
}

@p6rt
Copy link
Author

p6rt commented Feb 13, 2016

From @moritz

Golfed even further​:

# vim​: ft=perl6

use v6;
use JSON​::Tiny​::Grammar;
use JSON​::Tiny​::Actions;

my $result = JSON​::Tiny​::Grammar.parse( '{}', :actions(JSON​::Tiny​::Actions));
say $result.perl;

@p6rt
Copy link
Author

p6rt commented Feb 13, 2016

From @moritz

The underlying culprit is that deep down in that Match object there's a .made that's a Seq that has been iterated already​:

# vim​: ft=perl6

use v6;
use JSON​::Tiny​::Grammar;
use JSON​::Tiny​::Actions;

my $result = JSON​::Tiny​::Grammar.parse( '{}', :actions(JSON​::Tiny​::Actions));
say $result<value><object><pairlist>.made.^name; # Seq
say $result<value><object><pairlist>.made.perl; # dies with "Seq has already been iterated"

Maybe the real bug here is that (already iterated Seq).perl throws an exception instead of reproducing a Seq that already been iterated :-)

@p6rt
Copy link
Author

p6rt commented Feb 14, 2016

From @moritz

Fixed with rakudo/rakudo@8ca26cebb4 and tested with Raku/roast@760dbe8465

@p6rt p6rt closed this as completed Feb 14, 2016
@p6rt
Copy link
Author

p6rt commented Feb 14, 2016

@moritz - Status changed from 'new' to 'resolved'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant