Сам себе обфускатор
Навеяно замечаниями СБ
Предположим, что есть такой вот фрагмент кода на perl:
my $ID = 0;modifyID($ID);
print "$ID\n" if ($ID > 0);
На первый взгляд условие if ($ID > 0) никогда не выполнится. Действительно, переменная $ID передаётся в функцию по значению, следовательно, по выходе из неё значение переменной останется прежним. Однако, в perl возможно всё. Поэтому то, как показано ниже писать можно, но не нужно, чтобы не пугать гражданское население:
sub modifyID{
$_[0] = 1;
}
В подпрограмме modifyID я обратился непосредственно к $_ элементам массива @_, и произвёл изменения в фактических переменных, передаваемых подпрограмме. Плохо то, что такое поведение подпрограммы абсолютно не очевидно, если не заглядывать в код. Сам же код подпрограммы может находиться совершенно в другом месте и вероятность того, что код скрипта будет "оптимизирован" выбрасыванием якобы никогда не выполняющегося условия очень высока.
Более гуманный способ – заставить передавать значение по ссылке. Код будет выглядеть так:
sub modifyID {
my $ID = shift;
$$ID = 1;
}
Для справки: shift удаляет из массива его первый элемент, сдвигает все оставшиеся в начало и возвращает удаленный элемент в качестве значения. Длина массива сокращается на 1.
Фрагмент кода стал выглядеть немного иначе:
my $ID = 0;
modifyID(\$ID);
print "$ID\n" if ($ID > 0);
Теперь переменная $ID не только передаётся по ссылке, но и при попытке передачи по значению perl выдаст сообщение об ошибке наподобие такого:
Can't use string ("0") as a SCALAR ref while "strict refs" in use at blabla.pl line 6.
Неплохое руководство по написанию подпрограмм нашёл здесь.