Как известно в perl 5.10 появилось много всяких вкусностей:
все новые операторы доступны по-умолчанию
Пример 1:
$a = 0 unless defined $a; #раньше
$a //= 0; # perl 5.10
Пример 2:
Допустим у нас есть массив
@types = qw/type1 type2 type3/;
и необходимо проверить наличие в нем некого элемента
if (grep {$a eq $_} @types ) {} # раньше
if ($a ~~ @types ) {} # perl 5.10 (самый быстрый способ для поиска элемента в массиве)
Так же появились новые конструкции и функции - state, given/when, say. Но они доступны после use feature ':5.10';
Решение:
use Modern::Perl;
Написав это, Вы получите use strict, use warnings, use feature ':5.10' и mro c3;
суббота, 21 ноября 2009 г.
среда, 11 ноября 2009 г.
Правильное использование временной переменной в цикле foreach
Классический перловый foreach цикл:
Вариант 1:
foreach my $element ( @list ) {
#some code
}
Вариант 2:
my $element;
foreach $element ( @list ) {
#some code
}
Сравнение:
Большинство, не задумываясь, используют первый вариант... и это правильно :). Но есть "программисты-оптимизаторы", которые используют второй вариант, аргументируя это тем, что он "быстрее" (забивая на то, что они засоряют пространство имен родительского блока). Не слушайте их!!! Первый вариант на 40% быстрее!!! (в атаче бенчмарк; хотя, естественно, чистое время перебора элементов может занимать меньше 1% времени обработки элементов )
Многих этот факт может удивить но все объясняется следующим образом: перл просто не использут предварительно объявленую вами переменную и объявляет свою с таким же именем.
Попробуйте сами:
my $element = "NOT_USED";
foreach $element ( 1..2 ) {
#some code
}
вторник, 20 октября 2009 г.
Подсветка ошибок при просмотре логов
Мы часто юзаюем команду tail для логов( например tail -f file.log ) и часто не хватает подсветки строчек, которые содержат строку "error".
Пример 1.
Следующий код подсветит целую строку красным, если она содержит слово "error":
tail -f file.log | perl -pe 's/^.*error.+$/\e[1;32;41m$&\e[0m/gim'
#ключ -p обрамляет программу в while (<>) { ... print $_}
Пример 2.
Тут строки со словами "error", "warn", "debug" будут подсвечиваться тремя разными цветами:
tail -f file.log | perl -pe 's/^.*error.+$/\e[1;32;41m$&\e[0m/gim or s/^.*debug.+$/\e[1;33;44m$&\e[0m/gim or s/^.*warn.+$/\e[1;33;45m$&\e[0m/gmi'
я написал небольшой скриптик который подсвечивает нужные строки по шаблону.
примеры использования:
tail -f file.log | hl -p error #подсветить ошибки
tail -f file.log | hl # подсвечивать ошибки и варнинги
cat file.log | hl -p warn ownpattern # подсвечивать варнинги и строки содержащие ownpattern
Скачать приложение
Пример 1.
Следующий код подсветит целую строку красным, если она содержит слово "error":
tail -f file.log | perl -pe 's/^.*error.+$/\e[1;32;41m$&\e[0m/gim'
#ключ -p обрамляет программу в while (<>) { ... print $_}
Пример 2.
Тут строки со словами "error", "warn", "debug" будут подсвечиваться тремя разными цветами:
tail -f file.log | perl -pe 's/^.*error.+$/\e[1;32;41m$&\e[0m/gim or s/^.*debug.+$/\e[1;33;44m$&\e[0m/gim or s/^.*warn.+$/\e[1;33;45m$&\e[0m/gmi'
я написал небольшой скриптик который подсвечивает нужные строки по шаблону.
примеры использования:
tail -f file.log | hl -p error #подсветить ошибки
tail -f file.log | hl # подсвечивать ошибки и варнинги
cat file.log | hl -p warn ownpattern # подсвечивать варнинги и строки содержащие ownpattern
Скачать приложение
понедельник, 10 августа 2009 г.
Term::ANSIColor (стандартный модуль) - раскрась терминал
Очень простой стандартный модуль, который великолепно справляется со своей задачей, а именно подсветить текст необходимым Вам цветом.
За деталями лезем в perldoc Term::ANSIColor
Пример 1.
use Term::ANSIColor;
print color 'bold blue';
print "This text is bold blue.\n";
print color 'reset';
print "This text is normal.\n";
print colored ("Yellow on magenta.\n", 'yellow on_magenta');
print "This text is normal.\n";
print colored ['yellow on_magenta'], "Yellow on magenta.\n";
Пример 2.
use Term::ANSIColor qw(:constants);
print BOLD BLUE ON_WHITE "This text will be bold blue on white background", RESET;
За деталями лезем в perldoc Term::ANSIColor
Пример 1.
use Term::ANSIColor;
print color 'bold blue';
print "This text is bold blue.\n";
print color 'reset';
print "This text is normal.\n";
print colored ("Yellow on magenta.\n", 'yellow on_magenta');
print "This text is normal.\n";
print colored ['yellow on_magenta'], "Yellow on magenta.\n";
Пример 2.
use Term::ANSIColor qw(:constants);
print BOLD BLUE ON_WHITE "This text will be bold blue on white background", RESET;
суббота, 25 июля 2009 г.
Сортировка Шварца
Представим, что у нас есть масив @ar , нужно получить масив @ar_new отортировав масив @ar следующим образом :
@ar_new = sort { slow_sub ($a) <=> slow_sub($b) } @ar
Все бы хорошо но для сортировки n елементов блок сравнения будет вызван примерно n log n раз, а каждое сравнение это двойной вызов slow_sub. И в данной ситуации сортировка Шварца все решает.
@ar_new = map { $_->[0] }
sort { $a->[1] <=> $b->[1] }
@ar_new = sort { slow_sub ($a) <=> slow_sub($b) } @ar
Все бы хорошо но для сортировки n елементов блок сравнения будет вызван примерно n log n раз, а каждое сравнение это двойной вызов slow_sub. И в данной ситуации сортировка Шварца все решает.
@ar_new = map { $_->[0] }
sort { $a->[1] <=> $b->[1] }
map { [ $_, slow_sub($_) ] } @ar;
Теперь slow_sub будет вызвана для каждого значени всего один раз.
среда, 15 июля 2009 г.
При присвоении перл возвращает переменную (вернее - lvalue), а не ее значение
Что это дает?
Пример 1.
Можно сделать замену в скопированной переменной(сохранив при этом оригинальную)
(my $new_var = $original_var) =~ s/pattern/replacement/;
Пример 2.
Запись вида :
$a += 2;
$a *= 3;
можно заменить на :
($a += 2) *= 3;
Пример 3.
Запись вида :
if ($x) {
$a->{key} = 1;
}else{
$b->{key} = 1;
}
Можно заменить на : ($x ? $a : $b)->{key} = 1
ЗЫ: с это особенностью нужно быть осторожным.
Например, код: 0 ? $a = 1 : $a = 2; print $a; # выведет 2(вроде правильно)
1 ? $a = 1 : $a = 2; print $a; # выведет тоже 2. Хотя это не самый лучший пример, в данном случае можно (и нужно) было бы записать $a = 1? 1: 2;
Пример 1.
Можно сделать замену в скопированной переменной(сохранив при этом оригинальную)
(my $new_var = $original_var) =~ s/pattern/replacement/;
Пример 2.
Запись вида :
$a += 2;
$a *= 3;
можно заменить на :
($a += 2) *= 3;
Пример 3.
Запись вида :
if ($x) {
$a->{key} = 1;
}else{
$b->{key} = 1;
}
Можно заменить на : ($x ? $a : $b)->{key} = 1
ЗЫ: с это особенностью нужно быть осторожным.
Например, код: 0 ? $a = 1 : $a = 2; print $a; # выведет 2(вроде правильно)
1 ? $a = 1 : $a = 2; print $a; # выведет тоже 2. Хотя это не самый лучший пример, в данном случае можно (и нужно) было бы записать $a = 1? 1: 2;
пятница, 10 июля 2009 г.
Вы знаете про стандартную перловую утилиту find2perl ?!
find2perl транслирует параметры команды "find" в перловый код, который использует стандартный модуль File::Find
смотреть perldoc perlutils
Пример:
find2perl . -user root -perm 4000 -print
выдаст следующий платформонезависимый код (функция wanted нас интересует больше всего )
#здесь было начало. выполнив пример можно увидеть весь код ;)
sub wanted {
my ($dev,$ino,$mode,$nlink,$uid,$gid);
(($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) &&
($uid == $uid{'root'}) &&
(($mode & 0777) == 04000) &&
print("$name\n");
}
смотреть perldoc perlutils
Пример:
find2perl . -user root -perm 4000 -print
выдаст следующий платформонезависимый код (функция wanted нас интересует больше всего )
#здесь было начало. выполнив пример можно увидеть весь код ;)
sub wanted {
my ($dev,$ino,$mode,$nlink,$uid,$gid);
(($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_)) &&
($uid == $uid{'root'}) &&
(($mode & 0777) == 04000) &&
print("$name\n");
}
Подписаться на:
Сообщения (Atom)