Tuesday, August 31, 2010

Использование функции map в void-контексте

Функция map может использоваться для изменения существующего списка, вместо создания нового:
map s/foo/bar/g, @list;

Здесь используется тот факт, что $_ является алиасом для каждого элемента из @list.
Начиная с версии 5.8.1, map принимает во внимание контекст и не создает результирующий список, когда он не нужен.  Однако, чаще встречается for c выражением:
s/foo/bar/ for @list;

Monday, August 23, 2010

No such file or directory: Couldn’t initialize cross-process lock in child (FreeBSD 8.0+apache 2.2.15+prefork MPM)

Недавно наткнулся на баг апача в FreeBSD, который проявляется при graceful-рестарте (например, при ротации логов). Выглядит это примерно так:
[Mon Aug 23 00:00:04 2010] [notice] Graceful restart requested, doing restart
[Mon Aug 23 00:00:04 2010] [emerg] (2)No such file or directory: Couldn't initialize cross-process lock in child (/var/log/accept.lock.74025) (5)
[Mon Aug 23 00:00:04 2010] [emerg] (2)No such file or directory: Couldn't initialize cross-process lock in child (/var/log/accept.lock.74025) (5)
[Mon Aug 23 00:00:06 2010] [alert] Child 57481 returned a Fatal error... Apache is exiting!


Для решения проблемы надо изменить параметр AcceptMutex в конфиге апача:
AcceptMutex fcntl 

Ссылка по теме.

Saturday, August 21, 2010

vim: вариации на тему :w[rite]

В документации vim-а к команде :w[rite] упоминается такой вариант использования:
 :[range]w[rite] [++opt] !{cmd}

Эта команда выполняет {cmd} и передает содержимое файла как стандартный ввод. Когда это может быть полезно ?

  1. Сохранение файла с рутовыми правами. К примеру, вы отредактировали какой-то конфиг, а прав на сохранение не оказалось (с кем не бывало?).  Можно сохранить файл под временным именем, а потом переместить. А можно воспользоваться такой командой (лучше создать для нее mapping):
    :w !sudo tee % > /dev/null


  2. При редактировании скриптов (например, perl), бывает удобно выполнить часть скрипта, отправив ее на вход интерпретатору. Для этого выделяем блок текста с помощью Shift-V и используем команду
    :w !perl


Friday, August 20, 2010

Perl: обход прототипов при вызове функции

Для того, чтобы Perl не использовал прототип функции для проверки аргументов, достаточно добавить знак & перед вызовом функции: &NAME(LIST).
Пример:
my @a = 1..4;
sub test($$$$) {}

test($a[0], $a[1], $a[2], $a[3]); # OK
test(@a[0..3]); # Not enough arguments for main::test
&test(@a[0..3]); # OK

Sunday, August 15, 2010

Perl re: исключение символа из класса

При использовании регулярных выражений иногда требуется соответствие какому-то классу символов (w, d, s), за исключением одного или более символа из этого класса. Например, все whitespace-символы (s), кроме пробела. Как правило, в таких случаях используется перечисление оставшихся символов класса:
/[trnf]/

В качестве альтернативы можно использовать двойное отрицание:
/[^S ]/

что означает "не non-whitespace или не пробел", или, иными словами, "whitespace и не пробел". Этот вариант кстати по мнению Benchmark на 30% быстрее.