Comments 41
С таким заголовком можно попасть в черный список Роскомнадзора. Будьте осторожны (с) Паблик Хабра
+44
Ну а вы не стреляйте себе в ногу. Сделайте вот так, и будет вам счастье и радость:
В любом случае гораздо более осмысленно проверять не только ссылку на массив, но чтобы этот массив ещё и не был пустым.
mysub(@$x && $x->[0] =~ /abc/, $x = []);
В любом случае гораздо более осмысленно проверять не только ссылку на массив, но чтобы этот массив ещё и не был пустым.
0
Гхм, ну хотя это не работает с включенной прагмой strict.
Тогда, рез уж автовивификация есть, проверка на истинность $x вообще не нужна, и можно сразу проверять значение нулевого элемента:
Тогда, рез уж автовивификация есть, проверка на истинность $x вообще не нужна, и можно сразу проверять значение нулевого элемента:
mysub($x->[0] =~ /abc/, $x = []);
0
Хм-м, но всё же, если вы хотите придерживаться своей изначальной логики, то вот такая вот конструкция уж точно спасёт отца русской демократии:
P.S. Извиняюсь за флуд :-)
mysub($x && $x->[0] =~ /abc/ || undef, $x = []);
P.S. Извиняюсь за флуд :-)
0
Я один не понимаю, зачем вы используете прототипы аргументов для процедур?
В текущем виде они, — зло.
В текущем виде они, — зло.
0
Я использую прототипы в этом примере, чтобы не было подозрения на ещё один возможный баг:
выдаёт
Связано это с тем что оператор =~ в list конексе выдаёт список совпадений (и сответственно пустой спискок, если совпадений нет), таким образом первый аргумент просто исчезает, остаётся только второй.
По поводу того что они зло:
У них другое назначение, не как в других языках. Они не предназначены для контроля параметров. Они предназначены для правильного распознавания контекста (scalar vs list) а так
же для вызова подпограмм без скобок.
подробнее здесь.
stackoverflow.com/questions/297034/why-are-perl-5s-function-prototypes-bad
www.perlmonks.org/?node_id=861966
Как говорят в статье правильнее было бы их назвать «parameter context templates»
use strict;
use warnings;
sub mysub
{
my ($a, $b) = @_;
print "a: $a\n";
print "b: $b\n";
}
my $x = [];
mysub( ($x && ($x->[0] =~ /abc/i)), "some text $x->[0]" );
выдаёт
a: some text
b:
use strict;
use warnings;
sub mysub($$)
{
my ($a, $b) = @_;
print "a: $a\n";
print "b: $b\n";
}
my $x = [];
mysub( ($x && ($x->[0] =~ /abc/i)), "some text $x->[0]" );
a:
b: some text
Связано это с тем что оператор =~ в list конексе выдаёт список совпадений (и сответственно пустой спискок, если совпадений нет), таким образом первый аргумент просто исчезает, остаётся только второй.
По поводу того что они зло:
У них другое назначение, не как в других языках. Они не предназначены для контроля параметров. Они предназначены для правильного распознавания контекста (scalar vs list) а так
же для вызова подпограмм без скобок.
подробнее здесь.
stackoverflow.com/questions/297034/why-are-perl-5s-function-prototypes-bad
www.perlmonks.org/?node_id=861966
Как говорят в статье правильнее было бы их назвать «parameter context templates»
+2
в Perl (как и во многих других языках) X && Y, в случае если X — false, возвратит не просто false (не выполняя Y), а возвратит сам X
Может быть я что-то не понимаю, но почему в результате булевой операции возвращается небулево значение? Вы не могли бы объяснить, зачем так сделано? Я еще понимаю такое поведение в строготипизируемых языках, но тут то такие фокусы не должны срабатывать.
0
Да так в любом языке, разве нет?
Часто используемое x = yy || zz на этом основано. Никому ведь не хочется в данном случае в x увидеть true или false. Хочется yy или zz, причём они могут быть скалярами или объектами.
ruby -e 'puts false && 3'
false
ruby -e 'puts nil && 3'
ruby -e 'puts false || "Hello"'
Hello
Часто используемое x = yy || zz на этом основано. Никому ведь не хочется в данном случае в x увидеть true или false. Хочется yy или zz, причём они могут быть скалярами или объектами.
0
Не во всех, например:
На мой взгляд — это крайне неявное поведение. А неявное поведение — прямая дорога к ошибкам. Чем меньше неявного поведения, тем сложнее ошибиться. Статья то как раз и про это.
а вместо странной булевой операции
я бы использовал симантически более правильный и такой же компактный тернарный оператор:
php -r 'var_dump(false || "Hello");'
bool(true)
На мой взгляд — это крайне неявное поведение. А неявное поведение — прямая дорога к ошибкам. Чем меньше неявного поведения, тем сложнее ошибиться. Статья то как раз и про это.
а вместо странной булевой операции
x = yy || zz
я бы использовал симантически более правильный и такой же компактный тернарный оператор:
x = (yy?:zz)
+3
Вы какие-то странные вещи говорите. Это крайне явное, документированное поведение.
Не бывает никаких «интуитивных операторов», а про php у меня такие интересные истории есть.
Не бывает никаких «интуитивных операторов», а про php у меня такие интересные истории есть.
+3
В ruby/perl, если хотите привести результат к явному boolean — можно использовать оператор '!!'. Что в общем то и делают — при передачи логического значения в функцию или возвращении логического значения, приводят его к boolean (кто знает что с ним функция будет делать — может попытается сериализовать или будет утечка памяти итд)
0
Это не булевые операции. Булевые это: | и & (без удвоения символов)
-1
Даже в такую чистую вещь как передача аргументов в функцию засунули свои грязные императивные ручки.
+2
Да, они передаются по ссылке. Вроде бы можно сделать
(как обычно и делается)
и вуаля — аргументы уже переданны не по ссылке а по значению. По крайней мере $b и $c можно изменять, ничего с оригиналом не случиться. Но нет, разница всё же есть…
sub a
{
my ($b,$c) = @_;
}
(как обычно и делается)
и вуаля — аргументы уже переданны не по ссылке а по значению. По крайней мере $b и $c можно изменять, ничего с оригиналом не случиться. Но нет, разница всё же есть…
0
Я лишь говорю о том, что во время формирования структуры аргументов производить какие-то операции с изменением переменных — дурная идея.
Если человек отлаживал код на Perl'е, то знает что $myvar->[0] может изменить переменную.
Если человек отлаживал код на Perl'е, то знает что $myvar->[0] может изменить переменную.
0
Я честно говоря на столько редко сталкивался с autovivification, что просто забыл про неё, если бы мне показали кусок кода где явно дело может быть только в autovivification я бы наверное вспомнил.
Ну тут регэксп выдал истину, в том случае когда искомой строки ну нигде поблизости в коде просто не было…
Ну тут регэксп выдал истину, в том случае когда искомой строки ну нигде поблизости в коде просто не было…
0
UFO just landed and posted this here
Я так понимаю всем понятно зачем писать такой код, да?
Тогда объясните мне, пожалуйста, ЗАЧЕМ ПИСАТЬ ТАКОЙ КОД!?
Тогда объясните мне, пожалуйста, ЗАЧЕМ ПИСАТЬ ТАКОЙ КОД!?
+3
Отлично! Дополнение в копилку к остальной тысяче способов отстрелить себе ногу в Perl.
(Я почти уверен, кстати, что этот случай описан в PBP)
(Я почти уверен, кстати, что этот случай описан в PBP)
0
Сомневаюсь
0
Корень проблемы в том что, например, ($x && $y) = Z не работает, т.к. ($x && $y) — не lvalue. Однако, при передаче в функцию оно ведёт себя как lvalue. Это даже вроде описано в perl parameter aliasing.
печатает 3.
use strict;
use warnings;
sub a
{
$_[0] = 3;
}
my $x = 0;
my $y = 5;
a($x && $y);
print "$x\n";
печатает 3.
0
О каком случае идёт речь?
Тут на лицо абсурдное условие было:
Первый раз перед тем как написать $errors->[0] мы проверили что есть $errors, а второй раз — нет.
Тут на лицо абсурдное условие было:
ok( ($errors && ($errors->[0] =~ /My Exception/i)), "should catch exception $errors->[0]" );
Первый раз перед тем как написать $errors->[0] мы проверили что есть $errors, а второй раз — нет.
0
Sign up to leave a comment.
Ещё один способ отстрелить себе ногу в Perl