2015-05-12 12 views
7

sto combattendo qualche eredità perl guardando come la seguente:perl stringa di interpolazione quando si utilizza il delimitatore pacchetto

sub UNIVERSAL::has_sub_class { 
    my ($package,$class) = @_; 
    my $all = all_packages(); 
    print "$package - $class", "\n"; 
    print "$package::$class", "\n"; 
    return exists $all->{"$package::$class"}; 
} 

su due sistemi differenti, due differenti installazioni Perl/versioni, questo codice si comporta in modo diverso, vale a dire il costrutto "$package::$class" è risolto correttamente con il nome del pacchetto corretto su un sistema, ma non sull'altro.

I seguenti diversi print uscite può essere visto durante l'esecuzione has_sub_class sui due sistemi diversi:

# print output on system 1 (perl v5.8.6): 
webmars::parameter=HASH(0xee93d0) - webmars::parameter::date 
webmars::parameter::date 

# print output on system 2 (perl v5.18.1): 
webmars::parameter=HASH(0x251c500) - webmars::parameter::date 
webmars::parameter=HASH(0x251c500)::webmars::parameter::date 

C'è stata alcuna modifica della stringa di interpolazione in mezzo perl v5.8.6 e v5.18.1 perl che conoscete potrebbe causa questo comportamento? O dovrei cercare altrove? Ho davvero provato googleing e ho letto le note di modifica perl, ma non ho trovato nulla di interessante.

Con la mia conoscenza limitata di perl, ho provato ad ottenere il più piccolo codice che possa riprodurre il problema che sto avendo. Ho trovato il seguente che spero sia rilevante:

# system 1 (perl v5.8.6): 
$ perl -e 'my %x=(),$x=bless(\%x),$y='bar';print "$x::$y\n";' 
bar 

# system 2 (perl v5.18.1): 
$ perl -e 'my %x=(),$x=bless(\%x),$y='bar';print "$x::$y\n";' 
main=HASH(0xec0ce0)::bar 

Le uscite sono diverse! Qualche idea ?

+0

'perl -Mstrict -we 'my% x =(), $ x = bless (\% x), $ y =' bar '; stampa" $ x :: $ y \ n ";'' –

+2

Potrebbe abbastanza facilmente essere un bug risolto nell'intervallo di 6 anni tra le versioni :). Ma ben fatto per un MCVE così conciso! – Sobrique

risposta

4

Shorter dimostrazione:

($x::, $x) = (1,2); print "$x::$x" 

$ perl5.16.3 -e '($x::, $x) = (1,2); print "$x::$x"' 
12 

$ perl5.18.1 -e '($x::, $x) = (1,2); print "$x::$x"' 
2::2 

sta riscaldando.

$ perl5.16.3 -MO=Concise =e 'print "$x::$x"' 
8 <@> leave[1 ref] vKP/REFC ->(end) 
1  <0> enter ->2 
2  <;> nextstate(main 1 -e:1) v:{ ->3 
7  <@> print vK ->8 
3  <0> pushmark s ->4 
-  <1> ex-stringify sK/1 ->7 
-   <0> ex-pushmark s ->4 
6   <2> concat[t3] sK/2 ->7 
-    <1> ex-rv2sv sK/1 ->5 
4     <#> gvsv[*x::] s ->5   <-  $x:: 
-    <1> ex-rv2sv sK/1 ->6 
5     <#> gvsv[*x] s ->6   <-  $x 
-e syntax OK 

$ perl5.18.1 -MO=Concise -e 'print "$x::$x"' 
a <@> leave[1 ref] vKP/REFC ->(end) 
1  <0> enter ->2 
2  <;> nextstate(main 1 -e:1) v:{ ->3 
9  <@> print vK ->a 
3  <0> pushmark s ->4 
-  <1> ex-stringify sK/1 ->9 
-   <0> ex-pushmark s ->4 
8   <2> concat[t4] sKS/2 ->9 
6    <2> concat[t2] sK/2 ->7 
-     <1> ex-rv2sv sK/1 ->5 
4     <#> gvsv[*x] s ->5   <-  $x 
5     <$> const[PV "::"] s ->6  <-  "::" 
-    <1> ex-rv2sv sK/1 ->8 
7     <#> gvsv[*x] s ->8   <-  $x 
-e syntax OK 

TL; DR. v5.16 analizza "$x::$x" come $x:: . $x. v5.18 come $x . "::" . $x. Non vedo alcun riferimento ovvio a questo cambiamento nel delta docs, ma continuerò a cercare.

+0

In effetti, sembra che ci fosse un bug nel codice che veniva silenziato a causa di tot '" $ x :: $ x "' analizzando come '$ x ::. $ x', vale a dire'" $ package :: $ class "' cercherebbe '$ package ::' invece di '$ package' e finirà per rimpiazzarlo con' 'nella stringa dato che non è definito. – Cricri

+0

Riscrivi che come '$ {package} :: $ class' per farlo funzionare in qualsiasi versione di perl. – mob

3

Quindi, la mia prova molto veloce conferma il problema - utilizzando

perl -Mstrict -we 'my %x=(),$x=bless(\%x),$y="bar";print "$x::$y\n";' 

(con la versione, ottengo un avvertimento bareword per 'bar').

L'errore che ottengo in 5.8.8 è "l'uso del valore non inizializzato nella concatenazione".

La differenza sembra essere che quando corro con perl -MO=Deparse ottengo:

my (%x) =(); 
my $x = bless (\%x); 
my $y = 'bar'; 
print "$x::$y\n"; 

Se corro su 5.20.2, però, ottengo:

my (%x) =(); 
my $x = bless (\%x); 
my $y = 'bar'; 
print "${x}::$y\n"; 

Quindi sì, c'è stata un cambiamento nel modo in cui viene analizzato lo stesso codice. Ma non sono del tutto sicuro di come ti possa aiutare, a parte forse illuminarti su cosa sta succedendo?

+0

Mi aiuta molto a capire da dove proviene il problema, se è l'interprete perl, o problemi nel codice. E in questo caso, è una combinazione di entrambi. – Cricri

Problemi correlati