Eug*_*kov 4 string quotes perl double-quotes single-quotes
According to this comment:
You also should not use single quotes in
print ">>${ '_<$filename' }<<\n". Instead try:print ">>${ \"_<$filename\" }<<\n"
I always thought that differences between " and ' are only that the string is interpreted or not.
I want to ask why at this context:
print ">>${ \"_<$filename\" }<<\n"
print ">>${ '_<$filename' }<<\n"
Run Code Online (Sandbox Code Playgroud)
perl prints different values?
Why I should use \" instead of just ' here?
小智 6
问题的简短答案$filename是在第一个示例中插值,而在第二个示例中没有插值。你为什么问?好家伙。带上颠簸的旅程。
首先,了解${...}表示法的含义。使用它的原因有两个:一是简单地将变量名与周围的文本区分开;二是将变量名与周围的文本区分开。另一种是取消引用由(代码)的BLOCK返回的值。
如果方括号的内容只是一个空词(可能带有空格),那么它只是一个简单的变量名。因此,字符串"$foo"以及字符串"${foo}"和字符串"${ foo }"都产生相同的结果。如果您需要直接在字符串中的变量后附加文本,这很方便:$foo.'bar'您可以说而不是说"${foo}bar"。这些符号在插值字符串之外也起作用:您可以说${foo} = 'bar'是否喜欢。
但这不是您的代码在做什么。不好了。您将双符号shot弹枪对准了您的脚。您正在评估方括号的内容作为代码,并将结果用作对变量的引用。通过将整个批次放在插值字符串中,这使您倍加困惑。让我们对解引用的概念不做任何更深的了解,因为这不是这里的主要问题。关键是,如果不是空洞的话,大括号中的内容将被有效地评估。
现在,了解一下,当Perl在插值字符串中到达“ $ {”表示法时,它必须决定在这里插值什么:普通变量名或代码。在不进行任何内插的情况下,它会寻找匹配的近括号。如果用这些括号定界的子字符串看起来不像是一个空词,那么它将被评估。您仍然需要在该区域中转义双引号,因为任何未转义的双引号都将被视为这是子集的外部字符串的最终定界符,而“块”的其余部分将在字符串之外。
考虑到这一点,我们可以看到您的第一个示例evals "_<$filename",而您的第二个示例evals '_<$filename'。那只是内插字符串之间的区别,而不是内插字符串之间的区别:第一个字符串已$filename替换为某些内容,而第二个字符串严格是字面值。
在这两种情况下,字符串都用于对名称令人反感的全局标量变量执行符号解引用,如果实际定义了该字符串,则会使您感到羞耻。说的越少越好。
如果您认为我在开玩笑,请大胆尝试使用此代码。
print "This, ${die qq(oops!\n)}, and this.\n";
Run Code Online (Sandbox Code Playgroud)
当然,这样的字符串代码和eval()正确的字符串代码之间的主要区别在于,eval()它将捕获异常并设置$ @。事实并非如此:它只是像普通代码块中那样死亡。
这引起了Perl的隐藏技巧之一。您不能内插像这样的方法调用$foo->bar,但是可以像这样那样取消对包含它的数组的引用。
print "@{[$foo->bar]}\n";
Run Code Online (Sandbox Code Playgroud)
总而言之,为了上帝的爱,请不要编写这样的代码。