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

anon hashref after operator treated as code block #34

Open
moregan opened this issue Feb 4, 2014 · 4 comments
Open

anon hashref after operator treated as code block #34

moregan opened this issue Feb 4, 2014 · 4 comments

Comments

@moregan
Copy link
Collaborator

moregan commented Feb 4, 2014

from Perl-Critic/Perl-Critic#192 , hash constructor parses as a code block

ppidump '0 || {b => 1, a => 1};'
                    PPI::Document
                      PPI::Statement
[    1,   1,   1 ]     PPI::Token::Number       '0'
[    1,   3,   3 ]     PPI::Token::Operator     '||'
                        PPI::Structure::Block   { ... }
                          PPI::Statement
[    1,   7,   7 ]         PPI::Token::Word     'b'
[    1,   9,   9 ]         PPI::Token::Operator         '=>'
[    1,  12,  12 ]         PPI::Token::Number   '1'
[    1,  13,  13 ]         PPI::Token::Operator         ','
[    1,  15,  15 ]         PPI::Token::Word     'a'
[    1,  17,  17 ]         PPI::Token::Operator         '=>'
[    1,  20,  20 ]         PPI::Token::Number   '1'
[    1,  22,  22 ]     PPI::Token::Structure    ';'

At least some other operators do not parse it as a block:

ppidump '0, {b => 1, a => 1};'
                    PPI::Document
                      PPI::Statement
[    1,   1,   1 ]     PPI::Token::Number       '0'
[    1,   2,   2 ]     PPI::Token::Operator     ','
                        PPI::Structure::Constructor     { ... }
                          PPI::Statement::Expression
[    1,   5,   5 ]         PPI::Token::Word     'b'
[    1,   7,   7 ]         PPI::Token::Operator         '=>'
[    1,  10,  10 ]         PPI::Token::Number   '1'
[    1,  11,  11 ]         PPI::Token::Operator         ','
[    1,  13,  13 ]         PPI::Token::Word     'a'
[    1,  15,  15 ]         PPI::Token::Operator         '=>'
[    1,  18,  18 ]         PPI::Token::Number   '1'
[    1,  20,  20 ]     PPI::Token::Structure    ';'
@moregan
Copy link
Collaborator Author

moregan commented Feb 5, 2014

Request for comments: are there more operators that dictate that what follows them must be a hash constructor and not a block?

%PPI::Lexer::CURLY_CLASSES contains, among other things, operators that cannot be immediately followed by a code block. Some of those, like '+' and 'return', are documented as such; others like 'bless' and (I assume) '||=' were determined experimentally. Have there been problems in the past trying to expand the list of operators trusted to not be followed by blocks? Can PPI take another bite out of the block/hash constructor ambiguity problem via these operators?

E.g., these compile (under 5.16.3 and 5.8.8):

perl -WE 'my $x = 0; $x ||= {};'
perl -WE 'my $x = 1; $x &&= {};'

and these don't:

perl -WE 'my $x = 0; $x ||= {;};'
perl -WE 'my $x = 1; $x &&= {;};'

The number of operators that don't accept a block on the right side appears to be large: ||, &&, &&=, //, //=, to name a few.

@adamkennedy
Copy link
Collaborator

Doing it manually this way is not strictly right. There are plenty of
things a hash could come after, but in many cases it is illegal code.

So I tend to ignore those cases.

Adam
On Feb 4, 2014 10:54 PM, "moregan" notifications@github.com wrote:

Request for comments: are there more operators that dictate that what
follows them must be a hash constructor and not a block?

%PPI::Lexer::CURLY_CLASSES contains, among other things, operators that
cannot be immediately followed by a code block. Some of those, like '+' and
'return', are documented as such; others like 'bless' and (I assume) '||='
were determined experimentally. Have there been problems in the past trying
to expand the list of operators trusted to not be followed by blocks? Can
PPI take another bite out of the block/hash constructor ambiguity problem
via these operators?

E.g., these compile (under 5.16.3 and 5.8.8):

perl -WE 'my $x = 0; $x ||= {};'
perl -WE 'my $x = 1; $x &&= {};'

and these don't:

perl -WE 'my $x = 0; $x ||= {;};'
perl -WE 'my $x = 1; $x &&= {;};'

The number of operators that don't accept a block on the right side
appears to be large: ||, &&, &&=, //, //=, to name a few.

Reply to this email directly or view it on GitHubhttps://github.com//issues/34#issuecomment-34141926
.

@moregan
Copy link
Collaborator Author

moregan commented Feb 5, 2014

Currently PPI disambiguates hashes and blocks by checking for a few cases where a hash interpretation of {} compiles and a block interpretation does not: 'scalar', '||=', ',', '=', '=>'. In practical terms:

  1. PPI should not be doing what it is doing
  2. PPI should be doing what it is doing, but no more, due to points not raised in this conversation yet
  3. PPI should be doing more of the same -- "not strictly right", but no less right that PPI in general. e.g.: &&=

Are you asserting (1) or (2)? If not, is there any reason to not pursue (3)?

@adamkennedy
Copy link
Collaborator

My general rule is that pp I should be able to correctly match all real
world production code.

Adam
On Feb 5, 2014 12:29 PM, "moregan" notifications@github.com wrote:

Currently PPI disambiguates hashes and blocks by checking for a few cases
where a hash interpretation of {} compiles and a block interpretation does
not: 'scalar', '||=', ',', '=', '=>'. In practical terms:

  1. PPI should not be doing what it is doing
  2. PPI should be doing what it is doing, but no more, due to points not
    raised in this conversation yet
  3. PPI should be doing more of the same -- "not strictly right", but no
    less right that PPI in general. e.g.: &&=

Are you asserting (1) or (2)? If not, is there any reason to not pursue
(3)?

Reply to this email directly or view it on GitHubhttps://github.com//issues/34#issuecomment-34236367
.

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

No branches or pull requests

3 participants