Около месяца собирал разные «хаки» на языке программирования Perl. Эта подборка наглядно демонстрирует, как в Perl одна-две строчки кода могут сделать больше, чем десять строк в каком-нибудь другом языке программирования.
Дополнение: См также Основы программирования на Perl .
1. Проверить, существует ли элемент (первый аргумент функции, передается по значению) в массиве (второй аргумент функции, передается по ссылке).
grep { $_ == $_ [ 0 ] } @ { $_ [ 1 ] } ; # важно: для строк использовать eq
}
2. Удалить из массива @arr элементы, которые есть в массиве @skip.
my $t = $_ ;
! grep { $_ == $t } @skip ; # важно: для строк использовать eq
} @arr ;
3. Скрипт замены строк в тексте.
while ( <> ) {
chomp ;
last if ( $_ eq «==end==» ) ;
/^([^=]*)=(.*)$/ and $r { $1 } = $2 ;
}
$d = join » , <>;
$d =~ s/$_/$r{$_}/g for ( keys %r ) ;
print $d ;
4. Вывести список имен файлов и каталогов в заданной директории, отсортированный по дате последнего доступа. Обычно глобы сортируют список по имени файлов и каталогов. Для сортировки по дате последнего изменения, заменить цифру 8 на 9.
5. Удалить повторяющиеся элементы в массиве.
@links = grep { ! $cnt { $_ } ++; } @links ;
То же самое с помощью List::MoreUtils.
# …
@links = uniq @links ;
6. Перемешать элементы массива.
my $j = rand ( @links ) ;
@links [ $_ , $j ] = @links [ $j , $_ ] ;
}
Сделать то же самое с помощью List::Util.
# …
@links = shuffle @links ;
7. Выбрать случайный элемент в массиве можно как минимум двумя способами. Можно перемешать элементы, как в предыдущем примере, и выбрать нулевой, а можно в одну строчку:
8. Аналог PHP функции urlencode.
Но лучше использовать URI::Escape.
# uri_escape, uri_unescape
9. Получить все строки файла.
10. Простой многопоточный обработчик.
use strict ;
use threads ;
use threads :: shared ;
use List :: Util qw/shuffle/ ;
use constant THREADS_NUM => 8 ;
my $cnt : shared = 0 ;
my @threads ;
my @lines ;
while ( <> ) { chomp ; push @lines , $_ ; }
@lines = shuffle @lines ;
push @threads , threads -> create ( &thread_func , $_ )
for ( 1 .. THREADS_NUM ) ;
$_ -> join for ( @threads ) ;
sub thread_func {
my ( $thid ) = @_ ;
my $my_cnt ;
while ( 1 ) {
{ lock ( $cnt ) ; $my_cnt = $cnt ++; }
last if ( $my_cnt >= @lines ) ;
parse_line ( $thid , $lines [ $my_cnt ] ) ;
}
}
sub parse_line {
my ( $thid , $line ) = @_ ;
print «thid = $thid, line = $line n » ;
sleep ( rand ( 3 ) ) ;
}
Для выполнения этого кода Perl должен быть собран с поддержкой потоков. У меня под FreeBSD этой поддержки не оказалось, а после пересборки перла потребовалось также обновить некоторые CPAN-модули. Будьте внимательны.
11. Работа с временными файлами:
# работа с временными файлами в Perl
# (c) Alexandr A Alexeev 2011 | http://remontka.com/
# подробности см в ‘man File::Temp’
use strict ;
use File :: Temp ;
# сгенерировать имя временного файла в заданном каталоге
# с указанным префиксом
my $tmp_fname = File :: Temp :: tempnam ( «./tmp» , «myprfx» ) ;
print «tmp_name = $tmp_fname n » ;
# получить имя временного файла в каталоге /tmp
my $tmp_fname2 = tmpnam ( ) ;
print «tmp_name = $tmp_fname2 n » ;
# получить хэндл временного файла в каталоге /tmp
my $fh = tmpfile ( ) ;
close $fh ;
# получить имя и хэндл временного файла
my ( $th , $tname ) = tmpnam ( ) ;
print «tname = $tname n » ;
close $th ;
12. Вырезаем HTML теги + пример работы с юникодом:
use utf8 ;
use HTML :: Entities ;
# …
utf8 :: decode ( $_ ) ;
s/<[^>]*>//g ;
decode_entities ( $_ ) ;
utf8 :: encode ( $_ ) ;
См также HTML::Strip .
13. Кроссплатформенное считывание файла в одну строку или в массив строк.
# …
my $data = read_file ( $filename ) ;
my @lines = read_file ( $filename ) ;
# удаляем символы новой строки
@lines = map { chomp ; $_ ; } @lines ;
14, 15, 16 … Coming soon?