Что делает эта строка в DBI.pm? - PullRequest
3 голосов
/ 13 июля 2011
603   $dsn =~ s/^dbi:(\w*?)(?:\((.*?)\))?://i
                         or '' =~ /()/; # ensure $1 etc are empty if match fails

Я не понимаю, для чего $dsn =~ s/^dbi:(\w*?)(?:\((.*?)\))?://i, даже больше сомнений по поводу '' =~ /()/, мне кажется бесполезным ..

Ответы [ 5 ]

4 голосов
/ 13 июля 2011

Первая часть извлекает две части строки DSN в виде:

dbi: первое совпадение ( необязательное второе совпадение ):

Эти совпадения будут помещены в $1 и $2 для использования в следующем коде. Вторая часть будет работать только в том случае, если матч был неудачным. Это достигается с помощью or, который закорачивает (т.е. не выполняет) второе выражение, если первое было успешным.

Как кратко сказано в комментарии, он гарантирует, что $1, $2 и т. Д. Пусты. Предположительно, более поздний код может проверить их и выдать соответствующую ошибку, если они не были установлены (то есть не удалось извлечь из строки dsn).

1 голос
/ 13 июля 2011

Это ясно из комментариев в коде:

602     # extract dbi:driver prefix from $dsn into $1
603     $dsn =~ s/^dbi:(\w*?)(?:\((.*?)\))?://i
604             or '' =~ /()/; # ensure $1 etc are empty if match fails

Если у вас есть проблемы с пониманием работы s// и m//, см. perlop и perlre .

1 голос
/ 13 июля 2011

равно-тильда, или =~, является оператором совпадения .

Попробуйте следующий код - поместите его в файл, сделайте исполняемый файл с chmod +x и запустите его:

#!/usr/bin/perl

$mystring = "Perl rocks.";

if ($mystring =~ /rocks/) {
  print("Matches");
} else {
  print("No match");
}

Будет выведено Matches.

Что касается вашего примера, он проверяет, находится ли строка подключения в правильном формате, и извлекает имя базы данных и т.д .:

print($dsn);

$dsn = "dbi:SQLPlatform:database_name:host_name:port";

$dsn =~ s/^dbi:(\w*?)(?:\((.*?)\))?://i
                             or '' =~ /()/; # ensure $1 etc are empty if match fails

print($dsn);

Выход database_name:host_name:port.

0 голосов
/ 18 июля 2011

Что осталось из ответов до сих пор, так это таинственная or '' =~ /()/. Без этой хитрости, $ 1 будет неопределенным, если совпадение не удастся. Код, вероятно, использует $ 1 в конкатенации или строку вскоре после этого соответствия. Выполнение этого с неопределенным значением $ 1 приведет к предупреждению «Использование неинициализированного значения $ 1 в конкатенации (.) Или строке», если действует use warnings. С этой or '' =~ /()/ хитростью в игре будет определен $ 1 (но пуст), если регулярное выражение не будет соответствовать. Это удерживает код, который использует $ 1 от выброса.

Комментарий # ensure $1 etc are empty if match fails неверен. Избавьтесь от этого и т. Д., И комментарий правильный. Это действие устанавливает только 1 доллар и 1 доллар. Этот код не устанавливает $ 2. $ 2 будет неопределенным, если регулярное выражение не совпадает.

0 голосов
/ 13 июля 2011

Если совпадение при захвате не удается, $ 1 может все еще содержать значение; значение последнего успешного захвата совпадения в той же динамической области, возможно, из некоторого другого предыдущего регулярного выражения. Похоже, что автор не хотел, чтобы неудачное совпадение оставляло значение в $ 1 из предыдущего регулярного выражения. Чтобы предотвратить это, он принудил захватить матч «всегда удастся», и ничто не было указано в паренях. Это означает, что будет совпадение и захват пустой строки. Другими словами, $ 1 теперь будет пустым, вместо того, чтобы содержать значение совпадения из некоторого предыдущего успешного совпадения.

Более распространенная идиома - это просто проверить успешность сопоставления перед выполнением любого кода, который будет полагаться на значение $ 1, например:

if( /(match)/ ) {
    say $1;
}

Несмотря на то, что это часто самый простой подход, к сожалению, код иногда бывает непростым, и принудительное выполнение этого теста в некотором сложном коде может усложнить сложный раздел. В таком случае может быть проще убедиться, что $ 1 не содержит ничего после неудачного совпадения, чем то, что содержалось до неудачного совпадения.

Я действительно думаю, что это хороший вопрос. Найти документацию о поведении # $ 1 после неудачного сопоставления нелегко в Perl POD. Я считаю, что более подробное объяснение можно найти либо в книге верблюдов, либо в книге лам Но сейчас у меня их нет под рукой, чтобы проверить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...