Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
unbust extra scope being introduced
When using the sugared object property form `{ say }`, the
property:method rule triggered (not the property:identifier rule
-- I think the former won simply by dint of being first), and
instead of failing outright, it got as far as entering a new
lexical scope, and *then* failing.

Which means that the function declared in the test code got
declared in a scope that was further nested than the one in
which it got called:

    f();
    my o = { say };
    sub f() { say("Mr. Bond") }

And so it failed.

I *think* the lesson for future grammar authors is this: don't
run any side effects until you're sure you're in the right
rule. In this case, `property:method` had time to run a side
effect, and then immediately fail before the backtracking
carried the parser into the right rule, `property:identifier`.

Closes #150.
  • Loading branch information
Carl Masak committed Jun 16, 2016
1 parent 554ee38 commit e2dd3e6
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 3 deletions.
8 changes: 5 additions & 3 deletions lib/_007/Parser/Syntax.pm
Expand Up @@ -250,9 +250,11 @@ grammar _007::Parser::Syntax {
rule property:identifier-expr { <identifier> ':' <value=EXPR> }
rule property:method {
<identifier>
:my $*insub = True;
<.newpad>
'(' ~ ')' <parameterlist>
'(' ~ ')' [
:my $*insub = True;
<.newpad>
<parameterlist>
]
<trait> *
<blockoid>:!s
<.finishpad>
Expand Down
13 changes: 13 additions & 0 deletions t/features/objects.t
Expand Up @@ -239,4 +239,17 @@ use _007::Test;
"`new` on object literals without the type is allowed but optional";
}

{
my $program = q:to/./;
f();
my o = { say };
sub f() { say("Mr. Bond") }
.

outputs
$program,
qq[Mr. Bond\n],
"using the short-form property syntax doesn't accidentally introduce a scope (#150)";
}

done-testing;

0 comments on commit e2dd3e6

Please sign in to comment.