perl 将单个变量封装在双引号中

发布于 2025-01-03 00:21:25 字数 407 浏览 0 评论 0原文

在 Perl 中,是否有任何理由将单个变量封装在双引号中(无连接)?

我经常在我正在开发的程序的源代码中发现这一点(由不再在这里工作的人在 10 年前编写):

my $sql_host = "something";
my $sql_user = "somethingelse";

# a few lines down
my $db = sub_for_sql_conection("$sql_host", "$sql_user", "$sql_pass", "$sql_db");

据我所知,没有理由这样做。当我使用旧脚本时,我通常会删除引号,以便我的编辑器将它们着色为变量而不是字符串。

我认为他们在某处看到了这一点并复制了这种风格,但不明白为什么会这样。我错过了什么吗?

谢谢。

In Perl, is there any reason to encapsulate a single variable in double quotes (no concatenation) ?

I often find this in the source of the program I am working on (writen 10 years ago by people that don't work here anymore):

my $sql_host = "something";
my $sql_user = "somethingelse";

# a few lines down
my $db = sub_for_sql_conection("$sql_host", "$sql_user", "$sql_pass", "$sql_db");

As far as I know there is no reason to do this. When I work in an old script I usualy remove the quotes so my editor colors them as variables not as strings.

I think they saw this somewhere and copied the style without understanding why it is so. Am I missing something ?

Thank you.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

一场春暖 2025-01-10 00:21:25

这一切所做的就是显式地对变量进行字符串化。在 99.9% 的情况下,这是某种新手错误。

这种调用方式可能会产生一些副作用:

my $foo = "1234";
sub bar { $_[0] =~ s/2/two/ }
print "Foo is $foo\n";
bar( "$foo" );
print "Foo is $foo\n";
bar( $foo );
print "Foo is $foo\n";

这里,字符串化创建了一个副本并将其传递给子例程,从而绕过了 Perl 的按引用传递语义。通常认为修改调用变量是不礼貌的行为,所以你可能没问题。

您还可以在此处对对象或其他值进行字符串化。例如,undef 字符串化为空字符串。对象可以指定在字符串化时运行的任意代码。可以有具有不同数值和字符串值的双值标量。这是一种指定您想要字符串形式的方法。

还有一件可能正在发生的令人毛骨悚然的事情。如果您正在使用查看函数标量参数上设置的标志的 XS 代码,则对标量进行字符串化是对 perl 说的一种直接方式,“为我创建一个漂亮的干净的新字符串值”,仅使用字符串标志和没有数字标志。

我确信 99.9% 规则还有其他奇怪的例外。这是一些。在删除引号之前,请花一点时间检查一下是否有像这样的奇怪的废话。如果您确实发现了合法的用法,请添加一条评论,将这些引用标识为可行的拼凑,并给出它们存在的理由。

All this does is explicitly stringify the variables. In 99.9% of cases, it is a newbie error of some sort.

There are things that may happen as a side effect of this calling style:

my $foo = "1234";
sub bar { $_[0] =~ s/2/two/ }
print "Foo is $foo\n";
bar( "$foo" );
print "Foo is $foo\n";
bar( $foo );
print "Foo is $foo\n";

Here, stringification created a copy and passed that to the subroutine, circumventing Perl's pass by reference semantics. It's generally considered to be bad manners to munge calling variables, so you are probably okay.

You can also stringify an object or other value here. For example, undef stringifies to the empty string. Objects may specify arbitrary code to run when stringified. It is possible to have dual valued scalars that have distinct numerical and string values. This is a way to specify that you want the string form.

There is also one deep spooky thing that could be going on. If you are working with XS code that looks at the flags that are set on scalar arguments to a function, stringifying the scalar is a straight forward way to say to perl, "Make me a nice clean new string value" with only stringy flags and no numeric flags.

I am sure there are other odd exceptions to the 99.9% rule. These are a few. Before removing the quotes, take a second to check for weird crap like this. If you do happen upon a legit usage, please add a comment that identifies the quotes as a workable kludge, and give their reason for existence.

煮酒 2025-01-10 00:21:25

在这种情况下,双引号是不必要的。此外,使用它们的效率很低,因为这会导致原始字符串被复制。

但是,有时您可能想使用此样式来“字符串化”对象。例如, URI 对象支持字符串化:

my $uri = URI->new("http://www.perl.com");
my $str = "$uri";

In this case the double quotes are unnecessary. Moreover, using them is inefficient as this causes the original strings to be copied.

However, sometimes you may want to use this style to "stringify" an object. For example, URI ojects support stringification:

my $uri = URI->new("http://www.perl.com");
my $str = "$uri";
落花随流水 2025-01-10 00:21:25

我不知道为什么,但这是 Perl 新手常用的模式。这通常是一种浪费(因为它在您发布的代码片段中),但我可以想到两种用途。


它的作用是创建一个与原始字符串具有相同值的新字符串,这在极少数情况下可能很有用。

在下面的示例中,显式复制是为了保护 $x 不被子程序修改,因为子程序修改了它的参数。

$ perl -E'
   sub f { $_[0] =~ tr/a/A/; say $_[0]; }
   my $x = "abc";
   f($x);
   say $x;
'
Abc
Abc

$ perl -E'
   sub f { $_[0] =~ tr/a/A/; say $_[0]; }
   my $x = "abc";
   f("$x");
   say $x;
'
Abc
abc

通过创建字符串的副本,它将对象字符串化。当处理根据其参数是否为引用来改变其行为的代码时,这可能很有用。

在以下示例中,显式字符串化已完成,因为 require 处理 @INC 中的引用的方式与字符串不同。

$ perl -MPath::Class=file -E'
   BEGIN { $lib = file($0)->dir; }
   use lib $lib;
   use DBI;
   say "ok";
'
Can't locate object method "INC" via package "Path::Class::Dir" at -e line 4.
BEGIN failed--compilation aborted at -e line 4.

$ perl -MPath::Class=file -E'
   BEGIN { $lib = file($0)->dir; }
   use lib "$lib";
   use DBI;
   say "ok";
'
ok

I don't know why, but it's a pattern commonly used by newcomers to Perl. It's usually a waste (as it is in the snippet you posted), but I can think of two uses.


It has the effect of creating a new string with the same value as the original, and that could be useful in very rare circumstances.

In the following example, an explicit copy is done to protect $x from modification by the sub because the sub modifies its argument.

$ perl -E'
   sub f { $_[0] =~ tr/a/A/; say $_[0]; }
   my $x = "abc";
   f($x);
   say $x;
'
Abc
Abc

$ perl -E'
   sub f { $_[0] =~ tr/a/A/; say $_[0]; }
   my $x = "abc";
   f("$x");
   say $x;
'
Abc
abc

By virtue of creating a copy of the string, it stringifies objects. This could be useful when dealing with code that alters its behaviour based on whether its argument is a reference or not.

In the following example, explicit stringification is done because require handles references in @INC differently than strings.

$ perl -MPath::Class=file -E'
   BEGIN { $lib = file($0)->dir; }
   use lib $lib;
   use DBI;
   say "ok";
'
Can't locate object method "INC" via package "Path::Class::Dir" at -e line 4.
BEGIN failed--compilation aborted at -e line 4.

$ perl -MPath::Class=file -E'
   BEGIN { $lib = file($0)->dir; }
   use lib "$lib";
   use DBI;
   say "ok";
'
ok
江湖彼岸 2025-01-10 00:21:25

在你的情况下,引号完全没有用。我们甚至可以说这是错误的,因为这不是惯用的,正如其他人所写的那样。

然而,有时可能需要引用变量:这会显式触发变量值的字符串化。如果某些值是对偶变量或者它们是具有 重载ed 字符串化。

这是一个双变量的示例:

use 5.010;
use strict;
use Scalar::Util 'dualvar';

my $x = dualvar 1, "2";
say 0+$x;
say 0+"$x";

输出:

1
2

In your case quotes are completely useless. We can even says that it is wrong because this is not idiomatic, as others wrote.

However quoting a variable may sometime be necessary: this explicitely triggers stringification of the value of the variable. Stringification may give a different result for some values if thoses values are dual vars or if they are blessed values with overloaded stringification.

Here is an example with dual vars:

use 5.010;
use strict;
use Scalar::Util 'dualvar';

my $x = dualvar 1, "2";
say 0+$x;
say 0+"$x";

Output:

1
2
野味少女 2025-01-10 00:21:25

我的理论一直是,来自其他语言的人有坏习惯。并不是他们在想“我会一直使用双引号”,而是他们只是没有想!

老实说,我曾经陷入过这个陷阱,因为我是从 Java 转到 Perl 的,所以肌肉记忆就在那里,并且一直在发挥作用。

PerlCritic 终于让我戒掉了这个习惯!

它肯定会让你的代码更高效,但是如果你没有考虑是否要对字符串进行插值,你很可能会犯愚蠢的错误,所以我会更进一步说这是危险的。

My theory has always been that it's people coming over from other languages with bad habits. It's not that they're thinking "I will use double quotes all the time", but that they're just not thinking!

I'll be honest and say that I used to fall into this trap because I came to Perl from Java, so the muscle memory was there, and just kept firing.

PerlCritic finally got me out of the habit!

It definitely makes your code more efficient, but if you're not thinking about whether or not you want your strings interpolated, you are very likely to make silly mistakes, so I'd go further and say that it's dangerous.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文