perl 5.14 -> perl5.18

Условия

perl 5.14:

> uname -a 
Linux ppcdev1 3.8.0-41-generic #60~precise1-Ubuntu SMP Fri May 16 00:18:00 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

> lsb_release -c
Codename: precise

> perl -v |grep version
This is perl 5, version 14, subversion 2 (v5.14.2) built for x86_64-linux-gnu-thread-multi

perl 5.18:

> uname -a
Linux ppcdev4 3.13.0-30-generic #55-Ubuntu SMP Fri Jul 4 21:40:53 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

> lsb_release -c
Codename:       trusty

> perl -v |grep version
This is perl 5, version 18, subversion 2 (v5.18.2) built for x86_64-linux-gnu-thread-multi

Порядок обхода ключей хеша

Разный от запуска к запуску

# результат одинаковый при разных запусках
5.14> for i in `seq 1 10` ; do perl -le 'print join ", ", keys {a=>1,b=>2,c=>3}' ; done |sort         
c, a, b
c, a, b
c, a, b
c, a, b
c, a, b
c, a, b
c, a, b
c, a, b
c, a, b
c, a, b

5.14> for i in `seq 1 10` ; do perl -le 'print join ", ", keys {a=>1,b=>2,c=>3}' ; done |sort |uniq -c
     10 c, a, b

# каждый раз результат разный
5.18> for i in `seq 1 10` ; do perl -le 'print join ", ", keys {a=>1,b=>2,c=>3}' ; done |sort  
a, b, c
b, a, c
b, a, c
b, c, a
b, c, a
c, a, b
c, a, b
c, a, b
c, a, b
c, b, a

5.18> for i in `seq 1 10` ; do perl -le 'print join ", ", keys {a=>1,b=>2,c=>3}' ; done |sort |uniq -c
      3 a, c, b
      2 b, a, c
      2 b, c, a
      1 c, a, b
      2 c, b, a

Важно: внутри одного и того же запуска порядок обхода одного и того же хеша -- одинаковый. Но обход "одинаковых" хешей уже разный.

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

5.14> perl -le '$h = {a=>1,b=>2,c=>3}; for (1 .. 10){print join ", ", keys $h;}' |sort |uniq -c
     10 c, a, b

5.14> perl -le 'for (1 .. 10){print join ", ", keys {a=>1,b=>2,c=>3};}' |sort |uniq -c 
     10 c, a, b

# обходим один и тот же хеш -- порядок один и тот же
5.18> perl -le '$h = {a=>1,b=>2,c=>3}; for (1 .. 10){print join ", ", keys $h;}' |sort |uniq -c 
     10 a, c, b

# в цикле создаем анонимные хеши с одинаковым содержанием -- порядок разный
5.18> perl -le 'for (1 .. 10){print join ", ", keys {a=>1,b=>2,c=>3};}' |sort |uniq -c          
      3 a, b, c
      2 a, c, b
      5 b, c, a

split

split " " и $sp = " "; split $sp вели себя по-разному, стали -- одинаково

обнаружилось при пересборке Template Toolkit 2.4

#результаты разные 

5.14> perl -le 'print join "_", split(" ", "  The dog")'
The_dog

5.14> perl -le '$sp = " "; print join "_", split($sp, "  The dog")'
__The_dog

# результат одинаковый

5.18> perl -le 'print join "_", split(" ", "  The dog")' 
The_dog

5.18> perl -le '$sp = " "; print join "_", split($sp, "  The dog")'
The_dog

perldelta http://perldoc.perl.org/5.18.0/perldelta.html:

split's first argument is more consistently interpreted

After some changes earlier in v5.17, split's behavior has been simplified: 
if the PATTERN argument evaluates to a string containing one space, it is treated the way that a _literal_ string containing one space once was.

sort

5.14> perl -le 'use List::MoreUtils qw/uniq/; @h = qw/z y x a d c b f g j e /; @h = sort uniq @h; print join ", ", @h;'
a, b, c, d, e, f, g, j, x, y, z

5.18> perl -le 'use List::MoreUtils qw/uniq/; @h = qw/z y x a d c b f g j e /; @h = sort uniq @h; print join ", ", @h;'
Sort subroutine didn't return single value at -e line 1.

# можно добавить скобок, вот так:
5.18> perl -le 'use List::MoreUtils qw/uniq/; @h = qw/z y x a d c b f g j e /; @h = sort (uniq(@h)); print join ", ", @h;'
a, b, c, d, e, f, g, j, x, y, z

# но осторожно, пробелы имеют значение:
5.18> perl -le 'use List::MoreUtils qw/uniq/; @h = qw/z y x a d c b f g j e /; @h = sort(uniq (@h)); print join ", ", @h;'
Sort subroutine didn't return single value at -e line 1.

5.18> perl -le 'use List::MoreUtils qw/uniq/; @h = qw/z y x a d c b f g j e /; @h = sort(uniq(@h)); print join ", ", @h;' 
a, b, c, d, e, f, g, j, x, y, z

# самое короткое исправление -- добавить +:
5.18> perl -le 'use List::MoreUtils qw/uniq/; @h = qw/z y x a d c b f g j e /; @h = sort +uniq @h; print join ", ", @h;'
a, b, c, d, e, f, g, j, x, y, z

perldoc -f sort

               Warning: syntactical care is required when sorting the list returned from a function.  If you want to sort the list returned by the
               function call "find_records(@key)", you can use:

                   @contact = sort { $a cmp $b } find_records @key;
                   @contact = sort +find_records(@key);
                   @contact = sort &find_records(@key);
                   @contact = sort(find_records(@key));

               If instead you want to sort the array @key with the comparison routine "find_records()" then you can use:

                   @contact = sort { find_records() } @key;
                   @contact = sort find_records(@key);
                   @contact = sort(find_records @key);
                   @contact = sort(find_records (@key));

Safe.pm

'ref-to-glob cast' trapped by operation mask

решение: внести в список разрешенных операций rv2gv

см. также

https://rt.cpan.org/Public/Bug/Display.html?id=89437

http://chimera.labs.oreilly.com/books/1234000001527/ch03.html

open строки с не-ASCII текстом

Чтобы открыть строчку как файл, надо ее сначала превратить в байтовую. На perl 5.14 работало и без этого, на 5.18 перестало.

Примеры (двойной энкодинг -- для демонстрации безопасности конструкции; без if is_utf8 уже закодированные данные портятся):

precise, без энкодинга, OK
> perl -le 'use utf8; $s = "что-то по-русски"; open($fh, "<", \$s); my $buf; read $fh, $buf, 8192; print qq!"$buf"!;'
"что-то по-русски"

precise, с энкодингом, OK:
> perl -MEncode -le 'use utf8; $s = "что-то по-русски"; utf8::encode($s) if utf8::is_utf8($s); utf8::encode($s) if utf8::is_utf8($s); open($fh, "<", \$s); my $buf; read $fh, $buf, 8192; print qq!"$buf"!;'
"что-то по-русски"

trusty, без энкодинга, FAIL
> perl -le 'use utf8; $s = "что-то по-русски"; open($fh, "<", \$s); my $buf; read $fh, $buf, 8192; print qq!"$buf"!;'           
""

trusty, с энкодингом, OK:
> perl -le 'use utf8; $s = "что-то по-русски"; utf8::encode($s) if utf8::is_utf8($s); utf8::encode($s) if utf8::is_utf8($s); open($fh, "<", \$s); my $buf; read $fh, $buf, 8192; print qq!"$buf"!;'
"что-то по-русски"

Work/perl5.18 (last edited 2015-09-03 10:33:19 by lena)