Все задачи

Где я? (Subversion)

22 Mar 2013

Однажды программист захотел написать скрипт, который делал бы что-то полезное с svn-рабочей копией. Сначала ему понадобилось определить, в каком каталоге происходит дело:

my $url = `svn info` =~ s/.*URL: (\S+).*/$1/s;
my $rroot = `svn info` =~ s/.*Repository Root: (\S+).*/$1/s;

Но уже на этих двух строчках что-то не заладилось…

Подсказка

Показать

Точнее говоря, программист получил сообщение

Can't modify quoted execution (``, qx) in substitution (s///) at line 1, near "s/.*URL: (\S+).*/$1/s;"

Разоблачение

Показать

В обеих строчках одинаковая проблема, посмотрим на первую. Из-за старшинства операций получается вот что:

my $url = (`svn info` =~ s/.*URL: (\S+).*/$1/s);

Однако поиск с заменой по шаблону выполняется “in place”, и в качестве левого аргумента требует Л-значение, а результат выполнения обратных кавычек таковым не является.

До версии 5.14 правильным вариантом было явно расставить скобки:

(my $url = `svn info`) =~ s/.*URL: (\S+).*/$1/s;
(my $rroot = `svn info`) =~ s/.*Repository Root: (\S+).*/$1/s;

А начиная с perl 5.14 оператор замены (s///) поддерживает модификатор r, который копирует исходное значение, выполняет подстановку на нем, и возвращает получившийся результат. Левый операнд не модифицируется, так что теперь можно сделать еще и так:

my $url = `svn info` =~ s/.*URL: (\S+).*/$1/sr;
my $rroot = `svn info` =~ s/.*Repository Root: (\S+).*/$1/sr;

Вариант со скобками по-прежнему остается правильным.