2011-01-23 10 views
9

En la siguiente declaración de subrutina anónima, Perl parece estar analizarlo como una llamada al método indirecto, más que como una subrutina:¿Por qué esta declaración de subrutina de anon se analiza como un método de objeto indirecto en Perl?

use 5.010; 
use strict; 
use warnings; 

sub proxy { 
    my $new = shift; 
    say "creating proxy: $new"; 
    sub :lvalue { 
     say "running proxy: $new"; 
     tie my $ret, 'Some::Package', shift, $new; 
     $ret 
    } 
} 

say "before"; 
my $p1 = proxy '_value'; 
say "p1 declared: $p1"; 
my $p2 = proxy 'value'; 
say "p2 declared: $p2"; 

que imprime:

 
before 
creating proxy: _value 
running proxy: _value 
Can't locate object method "TIESCALAR" via package "Some::Package" ... 

Si un return o my $sub = es agregado justo antes de sub :lvalue {..., todo funciona correctamente e imprime:

 
before 
creating proxy: _value 
p1 declared: CODE(0x4c7e6c) 
creating proxy: value 
p2 declared: CODE(0x1ea85e4) 

También funciona si el atributo :lvalue se elimina de la subrutina (pero, por supuesto, eso cambia la funcionalidad).

Así que mi pregunta es ¿por qué sucede esto? ¿Es esto un error en Perl relacionado con atributos en subrutinas anónimas? ¿Es por alguna razón un comportamiento esperado? Si es un error, ¿está registrado?

Respuesta

15

Debido a que el principio de una sentencia es un lugar válido para encontrar una etiqueta goto, y así la bareword sub seguido por un contador de colon se analiza como la etiqueta sub:, que es seguido por lvalue BLOCK, que se analiza como sintaxis objeto indirecto .

Si fuerza al analizador para buscar un término haciendo return sub : lvalue { ... } o my $foo = sub : lvalue { ... }, lo analiza como se esperaba.

Cuestiones relacionadas