15. Лучше сообщения
об ошибках
$str = “Привет, $name. Последний
визит был $last. Сейчас $time.”;
perldiag
16. Лучше сообщения
об ошибках
$str = “Привет, $name. Последний
визит был $last. Сейчас $time.”;
Use of uninitialized value in
concatenation (.) or string at hello.plx line 9.
perldiag
17. Лучше сообщения
об ошибках
$str = “Привет, $name. Последний
визит был $last. Сейчас $time.”;
Use of uninitialized value $time in
concatenation (.) or string at hello.plx line 9.
perldiag
43. Рекурсия!
sub fact {
my ($x) = @_; # must be +int
return $x if $x == 1;
return $x * fact($x - 1);
}
44. Рекурсия!
sub fact {
my ($x) = @_; # must be +int
return $x if $x == 1;
return $x * fact($x - 1);
}
45. Рекурсия!
my $fact = sub {
my ($x) = @_; # must be +int
return $x if $x == 1;
return $x * $fact->($x - 1);
};
46. Рекурсия!
my $fact = sub {
my ($x) = @_; # must be +int
return $x if $x == 1;
return $x * $fact->($x - 1);
};
47. Рекурсия!
my $fact; $fact = sub {
my ($x) = @_; # must be +int
return $x if $x == 1;
return $x * $fact->($x - 1);
};
48. Рекурсия!
my $fact; $fact = sub {
my ($x) = @_; # must be +int
return $x if $x == 1;
return $x * $fact->($x - 1);
};
49. Рекурсия!
use Scalar::Util qw(weaken);
my $fact = do {
my $f1; my $f2 = $f1 = sub {
my ($x) = @_;
return $x if $x == 1;
return $x * $f1->($x - 1);
};
weaken($f1);
$f1;
};
50. Рекурсия!
use 5.16.0; # current sub
my $fact = sub {
my ($x) = @_; # must be +int
return $x if $x == 1;
return $x * __SUB__->($x - 1);
};
53. autodie
open my $fh, ‘<‘, $filename
or die “couldn’t open $filename: $!”;
while (<$fh>) {
...
}
close $fh
or die “couldn’t close $filename: $!”;
autodie
55. autodie
use autodie;
open my $fh, ‘<‘, $filename;
while (<$fh>) {
no autodie;
rmdir or warn “couldn’t remove $_: $!”;
}
close $fh;
autodie
56. autodie
use autodie;
sub foo {
my $filename = shift;
open my $fh, ‘<‘, $filename;
while (<$fh>) {
...
}
} # неявный вызов close БЕЗ autodie
autodie
57. IO::File
sub stream_to_fh {
my ($self, $fh) = @_;
fileno $fh
or die “can’t stream to closed fh”;
while (my $hunk = $self->next_hunk) {
print {$fh} $hunk;
}
close $fh or die “error closing: $!”;
}
perlopentut
58. IO::File
sub stream_to_fh {
my ($self, $fh) = @_;
$fh->fileno
or die “can’t stream to closed fh”;
while (my $hunk = $self->next_hunk) {
$fh->print($hunk);
}
$fh->close or die “error closing: $!”;
}
perlopentut
59. IO::File
sub stream_to_fh {
...
$fh->print($hunk);
...
$fh->close or die “error closing: $!”;
}
open my $target, ‘>’, ‘/dev/null’
or die “can’t open bit bucket:$!”;
stream_to_fh($target);
perlopentut
60. IO::File
use IO::File;
sub stream_to_fh {
...
$fh->print($hunk);
...
$fh->close or die “error closing: $!”;
}
open my $target, ‘>’, ‘/dev/null’
or die “can’t open bit bucket:$!”;
stream_to_fh($target);
perlopentut
61. IO::File
use 5.14.0;
sub stream_to_fh {
...
$fh->print($hunk);
...
$fh->close or die “error closing: $!”;
}
open my $target, ‘>’, ‘/dev/null’
or die “can’t open bit bucket:$!”;
stream_to_fh($target);
perlopentut
62. IO::File
use 5.14.0; use autodie;
sub stream_to_fh {
...
$fh->print($hunk);
...
$fh->close or die “error closing: $!”;
}
open my $target, ‘>’, ‘/dev/null’
or die “can’t open bit bucket:$!”;
stream_to_fh($target);
perlopentut
72. «Умное» сравнение
• если $x и $y неизвестны, то существует
23 возможные вариации
• и некоторые из них — рекурсивные
• нет, вы не будет помнить их все
• ... и они не интуитивные
perldoc
73. «Умное» сравнение
• если $x и $y неизвестны, то существует
23 возможные вариации
• и некоторые из них — рекурсивные
• нет, вы не будет помнить их все
• ... и они не интуитивные
perldoc
74. «Умное» сравнение
• если $x и $y неизвестны, то существует
23 возможные вариации
• и некоторые из них — рекурсивные
• нет, вы не будет помнить их все
• ... и они не интуитивные
perldoc
75. «Умное» сравнение
• если $x и $y неизвестны, то существует
23 возможные вариации
• и некоторые из них — рекурсивные
• нет, вы не будет помнить их все
• ... и они не интуитивные
perldoc
103. $@
• Ну, на самом деле, вы используете
Try::Tiny, верно?
• И это тоже делает Try::Tiny более
надёжным!
• Вы видите, что eval и $@ — полностью
ужасны
Try::Tiny
104. $@
• Ну, на самом деле, вы используете
Try::Tiny, верно?
• И это тоже делает Try::Tiny более
надёжным!
• Вы видите, что eval и $@ — полностью
ужасны
Try::Tiny
105. $@
• Ну, на самом деле, вы используете
Try::Tiny, верно?
• И это тоже делает Try::Tiny более
надёжным!
• Вы видите, что eval и $@ — полностью
ужасны
Try::Tiny
106. use 5.12.0;
{
package X;
sub DESTROY {
eval { }
}
}
eval {
my $x = bless {} => ‘X’;
die “DEATH!!”;
};
warn “ERROR: $@”;
$ perl5.12.4 test.pl
ERROR:
perlfunc
107. use 5.12.0;
{
package X;
sub DESTROY {
eval { }
}
}
eval {
my $x = bless {} => ‘X’;
die “DEATH!!”;
};
warn “ERROR: $@”;
$ perl5.12.4 test.pl
ERROR:
perlfunc
108. use 5.14.0;
{
package X;
sub DESTROY {
eval { }
}
}
eval {
my $x = bless {} => ‘X’;
die “DEATH!!”;
};
warn “ERROR: $@”;
$ perl5.12.4 test.pl
ERROR:
perlfunc
109. use 5.14.0;
{
package X;
sub DESTROY {
eval { }
}
}
eval {
my $x = bless {} => ‘X’;
die “DEATH!!”;
};
warn “ERROR: $@”;
$ perl5.14.1 test.pl
ERROR: DEATH!!
perlfunc
124. «Unicode-баг»
• строка не всегда рассматриваются
как Unicode
• это вызывает странные ошибки, для
поиска которых требуется время
• use feature ‘unicode_strings’;
•
perlunicode
125. «Unicode-баг»
• строка не всегда рассматриваются
как Unicode
• это вызывает странные ошибки, для
поиска которых требуется время
• use feature ‘unicode_strings’;
•
perlunicode
126. «Unicode-баг»
• строка не всегда рассматриваются
как Unicode
• это вызывает странные ошибки, для
поиска которых требуется время
• use feature ‘unicode_strings’;
• или use 5.12.0
perlunicode
127. «Unicode-баг»
• строка не всегда рассматриваются
как Unicode
• это вызывает странные ошибки, для
поиска которых требуется время
• use feature ‘unicode_strings’;
• или use 5.12.0
perlunicode
128. Unicode eval
• eval $str
• это октеты или символы?
• что будет, если это включает в себя
«use utf8»
• или вы работаете под «use utf8»
perldoc
190. Новые модификаторы
# Только ASCII-символы:
die “Забавные неамериканские символы”
if $str =~ /P{ASCII}/;
$str =~ /...регулярное выражение.../;
perlre
192. study
my $re = qr{...выражение...};
my $str = q{...long complex...};
$str =~ $re; # slow!!
study $str; # does stuff
$str =~ $re; # fast!!
perldoc
193. study
my $re = qr{...выражение...};
my $str = q{...длинная строка...};
$str =~ $re; # slow!!
study $str; # does stuff
$str =~ $re; # fast!!
perldoc
194. study
my $re = qr{...выражение...};
my $str = q{...длинная строка...};
$str =~ $re; # медленно!!
study $str; # does stuff
$str =~ $re; # fast!!
perldoc
195. study
my $re = qr{...выражение...};
my $str = q{...длинная строка...};
$str =~ $re; # медленно!!
study $str; # используем
$str =~ $re; # fast!!
perldoc
196. study
my $re = qr{...выражение...};
my $str = q{...длинная строка...};
$str =~ $re; # медленно!!
study $str; # используем
$str =~ $re; # быстро!!
perldoc
197. study
my $re = qr{...выражение...};
my $str = q{...длинная строка...};
$str =~ $re; # медленно, но верно!!
study $str; # используем
$str =~ $re; # кто знает!!
perldoc
198. study
my $re = qr{...выражение...};
my $str = q{...длинная строка...};
$str =~ $re; # медленно, но верно!!
study $str; # используем
$str =~ $re; # медленно, но верно!!
perldoc
206. $[ — индекс первого
элемента в массиве
• можно сделать так, чтобы $array[1]
возвращал первый элемент массива
• разве это не круто?
• это так же круто, как и шрифт Comic Sans
perlvar
207. $[ — индекс первого
элемента в массиве
• можно сделать так, чтобы $array[1]
возвращал первый элемент массива
• разве это не круто?
• это так же круто, как и шрифт Comic Sans
perlvar
208. $[ — индекс первого
элемента в массиве
• можно сделать так, чтобы $array[1]
возвращал первый элемент массива
• разве это не круто?
• это так же круто, как и шрифт Comic Sans
perlvar
209. $[ — индекс первого
элемента в массиве
• можно сделать так, чтобы $array[1]
возвращал первый элемент массива
• разве это не круто?
• это так же круто, как и шрифт Comic Sans
perlvar