Конкатенация строк в Perl с помощью «join» - PullRequest
8 голосов
/ 18 ноября 2010

См. Обновление ниже

Я прохожу целую кучу сценариев Perl, написанных кем-то из моей компании. Он использовал join для объединения строк. Например, он делает это (взято из реального сценария Perl):

$fullpath=join "", $Upload_Loc, "/", "$filename";

Вместо этого:

$fullpath = "$Upload_Loc" . "/" . "$filename";

Или даже просто так:

$fullpath = "$Upload_Loc/$filename";

Его больше нет, но люди, которые здесь присутствуют, говорят мне, что он связал строки таким образом, потому что это было как-то лучше . (Они не слишком ясно, почему).

Итак, почему кто-то использует join в этом вопросе, вместо использования оператора конкатенации ., или просто набирает строки вместе, как в третьем примере? Есть ли веская причина для такого стиля кодирования?

Я пытаюсь навести порядок здесь, и моей первой мыслью было бы положить конец этой практике. Это затрудняет чтение кода, и я уверен, что join не очень эффективный способ объединения строк. Однако, хотя я писал сценарии на Perl начиная с версии 3.x, я не считаю себя гуру, потому что у меня никогда не было возможности общаться с людьми, которые были лучше Perl, чем я, и могли бы научить меня Глубокие внутренние секреты Perl. Я просто хочу убедиться, что мой инстинкт здесь правильный, прежде чем я обманываю себя.

У меня есть лучшие способы сделать это здесь.


Обновление

Люди запутываются. Он не только для объединения путей. Вот еще один пример:

$hotfix=join "", "$app", "_", "$mod", "_", "$bld", "_", "$hf", ".zip";

Где, как я бы сделал что-то вроде этого:

$hotfix = $app . "_"  $mod . "_" . $bld . "_" . "$hf.zip";

Или, более вероятно,

$hotfix = "${app}_${mod}_${bld}_${hf}.zip";

Или, может быть, в этом случае я мог бы использовать join, потому что подчеркивание вызывает проблемы:

$hotfix = join("_", $app, $mod, $bld, $hf) . ".zip";

Мой вопрос до сих пор: делает ли он что-то, что знают настоящие хакеры Perl, и такой новичок, как я, который занимается этим всего 15 лет, не знает? Люди смотрят на меня, объединяя строки, используя ., или просто помещают их в кавычки и говорят: «Ха! Какой нуб! Уверен, у него тоже есть Macintosh!»

Или у предыдущего парня просто есть уникальный стиль программирования, очень похожий на уникальный стиль вождения моего сына, который включает в себя бегущую голову по деревьям?

Ответы [ 7 ]

6 голосов
/ 18 ноября 2010

Я сделал большую часть своей коммерческой разработки на Perl для "известного онлайн-ритейлера", и я никогда не видел, чтобы join использовался таким образом.Ваш третий пример будет моей предпочтительной альтернативой, так как он простой, чистый и читаемый.

Как и другие здесь, я не вижу никакой реальной ценности в использовании join в качестве средства повышения производительности.Он вполне может работать немного лучше, чем интерполяция строк, но я не могу представить реальную ситуацию, когда оптимизация может быть оправдана, но код все еще написан на языке сценариев.

Как показывает этот вопрос, идиомы эзотерического программирования(на любом языке) просто приведет к большому недоразумению.Если вам повезет, недоразумение будет добрым.Разработчики, с которыми мне нравится работать, - это те, кто кодирует читабельность и последовательность и оставляет Perl Golf на выходные.:)

Короче говоря: да, я думаю, что его уникальный стиль сродни уникальному стилю вождения вашего сына.:)

4 голосов
/ 18 ноября 2010

Я бы рассмотрел

$fullpath = join "/", $Upload_Loc, $filename;

понятнее, чем альтернативы. Однако File :: Spec был в ядре долгое время, поэтому

use File::Spec::Functions qw( catfile );
# ...
$fullpath = catfile $Upload_Loc, $filename;

намного лучше. И, что еще лучше, есть Path :: Class :

use Path::Class;

my $fullpath = file($Upload_Loc, $filename);

Скорость, как правило, не учитывается при объединении имен и путей к файлам.

Пример, который вы приводите в своем обновлении:

$hotfix=join "", "$app", "_", "$mod", "_", "$bld", "_", "$hf", ".zip";

демонстрирует, почему этот парень невежественен. Во-первых, нет необходимости интерполировать эти отдельные переменные. Во-вторых, это лучше написать как

$hotfix = join '_', $app, $mod, $bld, "$hf.zip";

или, альтернативно, как

$hotfix = sprintf '%s_%s_%s_%s.zip', $app, $mod, $bld, $hf;

с уменьшением ненужных знаков препинания является моей конечной целью.

3 голосов
/ 18 ноября 2010

Как правило, если списки элементов, которые нужно объединить, не являются большими, вы не увидите значительной разницы в производительности, если их объединить в конкатенацию. Основное беспокойство вызывает удобочитаемость и удобство обслуживания, и в этих случаях, если форма интерполяции строк более понятна, вы, безусловно, можете использовать это.

Я бы предположил, что это всего лишь личное предпочтение кодирования исходного программиста.

В общем, я использую join, когда длина списка велика / неизвестна, или если я соединяюсь с чем-то, кроме пустой строки (или с одним пробелом для интерполяции массива). В противном случае использование . или простая интерполяция строк обычно короче и проще для чтения.

2 голосов
/ 18 ноября 2010

Perl компилирует строки в двойных кавычках в вещи с цепочкой join и .:

$ perl -MO=Deparse,-q -e '$fullpath = "$Upload_Loc/$filename"'
$fullpath = $Upload_Loc . '/' . $filename;
-e syntax OK

$ perl -MO=Deparse,-q -le 'print "Got @ARGV"'
BEGIN { $/ = "\n"; $\ = "\n"; }
print 'Got ' . join($", @ARGV);
-e syntax OK

, которая может вдохновить вас на такие вещи:как в:

$ perl -le 'print $rx = do { local $" = "\t|\n\t"; qr{ ^ (?xis: @ARGV ) $ }mx }' good stuff goes here
(?^mx: ^ (?xis: good    |
        stuff   |
        goes    |
        here ) $ )

Отлично, а?

1 голос
/ 18 ноября 2010

Интерполяция немного медленнее, чем присоединение к списку. Тем не менее, я никогда не знал никого, кто довел бы это до такой крайности.

Вы можете использовать модуль Benchmark, чтобы определить разницу.

Кроме того, вы можете задать этот вопрос на http://perlmonks.org/. Там есть настоящие гуру, которые, вероятно, могут дать вам внутренние секреты гораздо лучше, чем я.

0 голосов
/ 21 ноября 2010

Признавая, что во всех примерах, которые я вижу здесь, нет существенных различий в производительности, серия конкатенации, с . или с двойной квотной интерполяцией, действительно будет более неэффективной по сравнению с объединением , который предварительно вычисляет необходимый строковый буфер для результата, а не расширяет его несколько раз (возможно, даже при необходимости каждый раз перемещать частичный результат в новое место).

У меня проблема с критикой, которую я вижу здесь; Есть много правильных способов говорить на Perl, и это, безусловно, один из них.

Несоответствующий отступ, с другой стороны ...

0 голосов
/ 18 ноября 2010

Все эти подходы хороши.

Присоединение иногда может быть более мощным, чем . concatentate, особенно когда некоторые вещи, к которым вы присоединяетесь, являются массивами:

join "/", "~", @document_path_elements, $myDocument;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...