2015-05-12 3 views
7

борется немного устаревшая Perl выглядит как следующее:Perl строка интерполяции при использовании пакета разделителя

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

На два разных системах, два различных PERL установок/версию, этот код ведет себя по-разному, т.е. "$package::$class" конструкта правильно разрешено правильное имя пакета в одной системе, но не на другом.

следующих различных print выходов можно увидеть при запуске has_sub_class на два различных системах:

# 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 

Были ли какое-либо строка интерполяции изменения между PERL v5.8.6 и PERL v5.18.1, что вы знаете, мощь вызвать это поведение? Или я должен смотреть в другое место? Я действительно пробовал google-ing и читал записи изменений perl, но не мог найти ничего интересного.

С моим ограниченным знанием perl, я попытался получить наименьший фрагмент кода, который мог бы воспроизвести проблему, которую я испытываю. Я пришел к следующему:

# 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 

Выходы разные! Есть идеи ?

+0

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

+2

Не удалось довольно легко быть ошибкой, зафиксированной в промежуточные 6 лет между релизами :). Но хорошо сделано для такого краткого MCVE! – Sobrique

ответ

4

Шортер демонстрация:

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

Получение теплее.

$ 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 анализирует "$x::$x" как $x:: . $x. v5.18 как $x . "::" . $x. Я не вижу никакой очевидной ссылки на это изменение в delta docs, но я буду продолжать искать.

+0

Действительно, похоже, что ошибка в коде, который был отключен из-за '' $ x :: $ x '' разбора как '$ x ::. $ x', т.е.'' $ package :: $ class "' будет искать '$ package ::' вместо '$ package' и в конечном итоге заменить его' 'в строке, так как он не определен. – Cricri

+0

Перепишите это как '$ {package} :: $ class', чтобы заставить его работать в любой версии perl. – mob

3

Итак, мой очень быстрый тест подтверждает проблему - с помощью

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

(С версией, я получаю предупреждение bareword для «бара»).

Ошибка, которую я получаю в 5.8.8, - «использование неинициализированного значения в конкатенации».

Разница, кажется, что, когда я бегу с perl -MO=Deparse я получаю:

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

Если я бегу на 5.20.2, хотя, я получаю:

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

Так что да, там было изменение того, как разбор одного и того же кода. Но я не совсем уверен, как это поможет вам, кроме, возможно, просвещать вас о том, что происходит?

+0

Это очень помогает мне понять, откуда эта проблема, если это интерпретатор perl или проблемы в коде. И в этом случае это комбинация обоих. – Cricri

Смежные вопросы