2015-05-12 18 views
7

walczę trochę starszego Perl wygląda jak następuje:Perl interpolacja ciąg przy użyciu separatora pakiet

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"}; 
} 

na dwóch różnych systemów, dwa różne instalacje Perl/wersji, kod ten zachowuje się inaczej, tzn "$package::$class" konstruktu poprawnie rozwiązany pod prawidłową nazwą pakietu w jednym systemie, ale nie po drugiej.

następujących różnych print wyjść można zaobserwować podczas pracy has_sub_class na dwóch różnych systemach:

# 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 

Czy nastąpiły jakieś zmiany w ciąg interpolacji między perl v5.8.6 i Perl v5.18.1 które znają potęgę spowodować to zachowanie? A może powinienem szukać gdzieś indziej? Naprawdę próbowałem googlować i czytać notatki zmian perla, ale nie mogłem znaleźć niczego interesującego.

Z moją ograniczoną znajomością perla, próbowałem uzyskać najmniejszy fragment kodu, który mógłby odtworzyć problem, który mam. Wymyśliłem następujące informacje, które mam nadzieję mają znaczenie:

# 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 

Wyniki są różne! Jakieś pomysły ?

+0

'perl -Mstrict -we 'my% x =(), $ x = błogosław (\% x), $ y =' bar ', wydrukuj" $ x :: $ y \ n ";'' –

+2

Może dość łatwo można naprawić błąd w przeciągu 6 lat między wydaniami :). Ale dobrze zrobione za tak zwięzłe MCVE! – Sobrique

Odpowiedz

4

Krótszy demonstracji:

($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 

coraz cieplej.

$ 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 analizuje "$x::$x" jako $x:: . $x. v5.18 jako $x . "::" . $x. Nie widzę żadnego oczywistego odniesienia do tej zmiany w delta docs, ale będę dalej szukać.

+0

Rzeczywiście, wygląda na to, że w kodzie był błąd, który został wyciszony z powodu "$ x :: $ x" 'parsowania jako' $ x ::. $ x', tj.'" $ package :: $ class "' wyszukałoby '$ package ::' zamiast '$ package' i ostatecznie zastąpiło go' 'w ciągu znaków, ponieważ jest niezdefiniowane. – Cricri

+0

Przepisuj to jako '$ {package} :: $ class', aby działał w dowolnej wersji perla. – mob

3

Tak, moja bardzo szybki test potwierdza problem - korzystając

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

(Z wersji, otrzymuję ostrzeżenie gołe słowo dla 'bar').

Błąd, który pojawia się w 5.8.8, to "użycie niezainicjowanej wartości w konkatenacji".

Różnica wydaje się, że gdy uruchamiam z perl -MO=Deparse uzyskać:

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

Jeśli biegnę na 5.20.2 jednak uzyskać:

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

Więc tak, nastąpił zmiana sposobu analizowania tego samego kodu. Ale nie jestem do końca pewien, w jaki sposób ci to pomaga, oprócz być może oświecenia cię, co się dzieje?

+0

Bardzo pomaga mi zrozumieć, skąd bierze się problem, jeśli jest to interpreter perl lub problemy w kodzie. I w tym przypadku jest to połączenie obu. – Cricri

Powiązane problemy