请参阅下面的更新
我正在阅读我公司的某些人编写的一大堆Perl脚本。他使用join
来连接字符串。例如,他这样做(从真正的Perl脚本中取出来):
$fullpath=join "", $Upload_Loc, "/", "$filename";
而不是:
$fullpath = "$Upload_Loc" . "/" . "$filename";
或者就是这样:
$fullpath = "$Upload_Loc/$filename";
他已经不在了,但是在这里的人告诉我他以这种方式连接字符串,因为它在某种程度上更好。 (他们不太清楚为什么)。
那么,为什么有人在使用join
连接运算符时使用.
,或者只是像第三个例子那样键入字符串?这种编码风格是否有正当理由?
我正在努力清理这里的许多烂摊子,我的第一个想法是结束这种做法。它使代码更难阅读,我确信做join
不是一种连接字符串的非常有效的方法。然而,虽然自从3.x版以来我一直在用Perl编写脚本,但我并不认为自己是一个大师,因为我从来没有机会和Perl比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!”
或者,前一个人是否只有一个独特风格的编程,就像我儿子的独特风格的驾驶包括跑进树林一样?
答案 0 :(得分:6)
我为“一个知名的在线零售商”做了我公平的商业Perl开发,我从来没有见过join
这样的用法。你的第三个例子是我的首选,因为它简单,干净,易读。
与其他人一样,我认为使用join
作为性能增强器并没有任何真正的价值。它可能比字符串插值更好地执行,但我无法想象一个真实的情况,其中优化可能是合理的,但代码仍然用脚本语言编写。
正如这个问题所表明的那样,深奥的编程习语(用任何语言)只会导致很多误解。如果你很幸运,这种误解是良性的。我喜欢和他们一起工作的开发人员是编写可读性和一致性的代码,并在周末离开Perl Golf。 :)
简而言之:是的,我认为他独特的风格类似于你儿子独特的驾驶风格。 :)
答案 1 :(得分:4)
我会考虑
$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;
减少不必要的标点符号是我的最终目标。
答案 2 :(得分:3)
通常,除非要加入的项目列表很大,否则您将看不到很多性能差异,将它们更改为连接。主要关注的是可读性和可维护性,在这种情况下,如果字符串插值形式更清晰,您当然可以使用它。
我猜这只是原始程序员的个人编码偏好。
一般情况下,当列表的长度很大/未知时,或者我正在使用空字符串以外的其他内容(或用于数组插值的单个空格)时,我会使用join
。否则,使用.
或简单的字符串插值通常更短,更容易阅读。
答案 3 :(得分:2)
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
这可能会激发你这样的事情:
$rx = do { local $" = "|"; qr{^(?:@args)$} };
如:
$ perl -le 'print $rx = do { local $" = "\t|\n\t"; qr{ ^ (?xis: @ARGV ) $ }mx }' good stuff goes here
(?^mx: ^ (?xis: good |
stuff |
goes |
here ) $ )
Nifty,是吗?
答案 4 :(得分:1)
插值比加入列表慢一点。那说我从来不认识任何人把它带到这个极端。
您可以使用Benchmark
模块来确定存在多大差异。
另外,您可以在http://perlmonks.org/上提出这个问题。那里有真正的大师可能会比我更好地给你内心的秘密。
答案 5 :(得分:0)
所有这些方法都很好。
Join有时可能比.
concatentate更强大,特别是当您加入的某些内容是数组时:
join "/", "~", @document_path_elements, $myDocument;
答案 6 :(得分:0)
虽然认识到在我看到的所有示例中都没有明显的性能差异,但是无论是.
还是双引号插值,一系列连接确实会比内存效率低得多。一个join,它为结果预先计算所需的字符串缓冲区,而不是多次展开它(甚至可能需要每次都将部分resutl移动到一个新位置)。
我在这里看到的批评有问题;有很多正确的方式可以说perl,这肯定是其中之一。
另一方面,压痕不一致......