Perl 中的 my 和 local 有什么区别?

发布于 2024-07-05 21:25:54 字数 52 浏览 7 评论 0原文

我看到它们都用在我正在尝试调试的脚本中,但文献还不清楚。 有人能为我揭开这个神秘面纱吗?

I am seeing both of them used in this script I am trying to debug and the literature is just not clear. Can someone demystify this for me?

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

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

发布评论

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

评论(16

酒儿 2024-07-12 21:25:55

来自 man perlsub

与本地运算符创建的动态变量不同,用 my 声明的词法变量完全对外界隐藏,包括任何调用的子例程。

因此,过于简单化,< code>my 使您的变量仅在声明的地方可见。 local 也使其在调用堆栈中可见。 您通常需要使用 my 而不是 local

From man perlsub:

Unlike dynamic variables created by the local operator, lexical variables declared with my are totally hidden from the outside world, including any called subroutines.

So, oversimplifying, my makes your variable visible only where it's declared. local makes it visible down the call stack too. You will usually want to use my instead of local.

故事灯 2024-07-12 21:25:55

你的困惑是可以理解的。 词法作用域相当容易理解,但动态作用域是一个不寻常的概念。 由于历史原因,名称 mylocal 有点不准确(或至少不直观),这使得情况变得更糟。

my 声明一个词法变量——从声明点到封闭块(或文件)末尾都是可见的。 它完全独立于程序其余部分中具有相同名称的任何其他变量。 它是该块私有的。

另一方面,local 声明对全局变量值的临时更改。 更改在封闭范围的末尾结束,但变量(全局变量)在程序中的任何位置都可见。

根据经验,使用 my 声明您自己的变量,并使用 local 来控制 Perl 内置变量更改的影响。

有关更全面的描述,请参阅 Mark Jason Dominus 的文章应对范围界定

Your confusion is understandable. Lexical scoping is fairly easy to understand but dynamic scoping is an unusual concept. The situation is made worse by the names my and local being somewhat inaccurate (or at least unintuitive) for historical reasons.

my declares a lexical variable -- one that is visible from the point of declaration until the end of the enclosing block (or file). It is completely independent from any other variables with the same name in the rest of the program. It is private to that block.

local, on the other hand, declares a temporary change to the value of a global variable. The change ends at the end of the enclosing scope, but the variable -- being global -- is visible anywhere in the program.

As a rule of thumb, use my to declare your own variables and local to control the impact of changes to Perl's built-in variables.

For a more thorough description see Mark Jason Dominus' article Coping with Scoping.

聚集的泪 2024-07-12 21:25:55
&s;

sub s()
{
    local $s="5";
    &b;
    print $s;
}

sub b()
{
    $s++;
}

上面的脚本打印 6。

但是如果我们将 local 更改为 my,它将打印 5。

这就是区别。 简单的。

&s;

sub s()
{
    local $s="5";
    &b;
    print $s;
}

sub b()
{
    $s++;
}

The above script prints 6.

But if we change local to my it will print 5.

This is the difference. Simple.

太阳男子 2024-07-12 21:25:55

仅当您在子例程中调用子例程时,它才会有所不同,例如:

sub foo { 
    print "$x\n"; 
}
sub bar { my $x; $x = 2; foo(); }
    
bar(); 

它不打印任何内容,因为 $x 受 bar 的 {} 限制,并且对调用的子例程不可见,例如:

sub foo { print "$x\n"; }

sub bar { local $x; $x = 2; foo(); }
   
bar(); 

它将打印 2,因为局部变量对被调用的子例程可见。

It will differ only when you have a subroutine called within a subroutine, for example:

sub foo { 
    print "$x\n"; 
}
sub bar { my $x; $x = 2; foo(); }
    
bar(); 

It prints nothing as $x is limited by {} of bar and not visible to called subroutines, for example:

sub foo { print "$x\n"; }

sub bar { local $x; $x = 2; foo(); }
   
bar(); 

It will print 2 as local variables are visible to called subroutines.

泛滥成性 2024-07-12 21:25:55

查看以下代码及其输出以了解其中的差异。

our $name = "Abhishek";

sub sub1
{
    print "\nName = $name\n";
    local $name = "Abhijeet";

    &sub2;
    &sub3;
}

sub sub2
{
    print "\nName = $name\n";
}

sub sub3
{
    my $name = "Abhinav";
    print "\nName = $name\n";
}


&sub1;

输出是:

Name = Abhishek

Name = Abhijeet

Name = Abhinav

Look at the following code and its output to understand the difference.

our $name = "Abhishek";

sub sub1
{
    print "\nName = $name\n";
    local $name = "Abhijeet";

    &sub2;
    &sub3;
}

sub sub2
{
    print "\nName = $name\n";
}

sub sub3
{
    my $name = "Abhinav";
    print "\nName = $name\n";
}


&sub1;

Output is :

Name = Abhishek

Name = Abhijeet

Name = Abhinav
夏见 2024-07-12 21:25:55

local 是一种较旧的本地化方法,从 Perl 仅具有动态作用域的时代开始。 词法作用域对于程序员来说更加自然,并且在许多情况下更加安全。 我的变量属于声明它们的范围(块、包或文件)。

相反,局部变量实际上属于全局名称空间。 如果你用local引用变量$x,你实际上引用的是$main::x,它是一个全局变量。 与它的名称所暗示的相反,所有 local 所做的都是将新值推送到 $main::x 的值堆栈上,直到该块结束,此时旧值将被恢复。 这本身就是一个有用的功能,但由于多种原因,它并不是使用局部变量的好方法(想想当你有线程时会发生什么!并想想当你调用一个真正想要使用全局变量的例程时会发生什么)您已本地化!)。 然而,在 Perl 5 之前的糟糕日子里,这是让变量看起来像局部变量的唯一方法。我们仍然坚持它。

local is an older method of localization, from the times when Perl had only dynamic scoping. Lexical scoping is much more natural for the programmer and much safer in many situations. my variables belong to the scope (block, package, or file) in which they are declared.

local variables instead actually belong to a global namespace. If you refer to a variable $x with local, you are actually referring to $main::x, which is a global variable. Contrary to what it's name implies, all local does is push a new value onto a stack of values for $main::x until the end of this block, at which time the old value will be restored. That's a useful feature in and of itself, but it's not a good way to have local variables for a host of reasons (think what happens when you have threads! and think what happens when you call a routine that genuinely wants to use a global that you have localized!). However, it was the only way to have variables that looked like local variables back in the bad old days before Perl 5. We're still stuck with it.

睫毛上残留的泪 2024-07-12 21:25:55

“我的”变量仅在当前代码块中可见。 “局部”变量在以前可见的地方也可见。 例如,如果您说“my $x;” 并调用子函数,它看不到变量 $x。 但如果你说“本地$/;” (将记录分隔符的值清空)然后您可以更改在您调用的任何函数中读取文件的方式。

在实践中,你几乎总是想要“我的”,而不是“本地的”。

"my" variables are visible in the current code block only. "local" variables are also visible where ever they were visible before. For example, if you say "my $x;" and call a sub-function, it cannot see that variable $x. But if you say "local $/;" (to null out the value of the record separator) then you change the way reading from files works in any functions you call.

In practice, you almost always want "my", not "local".

蓝海似她心 2024-07-12 21:25:55

dinomite 使用 local 重新定义记录分隔符的示例是我在大量 perl 编程中遇到的唯一一次。 我生活在一个利基 perl 环境 [安全编程] 中,但根据我的经验,它确实是一个很少使用的范围。

dinomite's example of using local to redefine the record delimiter is the only time I have ran across in a lot of perl programming. I live in a niche perl environment [security programming], but it really is a rarely used scope in my experience.

抱猫软卧 2024-07-12 21:25:55

我认为最容易记住的方法就是这样。 MY 创建一个新变量。 LOCAL 临时更改现有变量的值。

I think the easiest way to remember it is this way. MY creates a new variable. LOCAL temporarily changes the value of an existing variable.

素食主义者 2024-07-12 21:25:55
#!/usr/bin/perl

sub foo { print ", x is $x\n"; }

sub testdefault { $x++; foo(); }        # prints 2

sub testmy { my $x; $x++; foo(); }       # prints 1

sub testlocal { local $x = 2; foo(); }    # prints 2. new set mandatory


print "Default, everything is global";
$x = 1;
testdefault();

print "My does not affect function calls outside";
$x = 1;
testmy();

print "local is everything after this but initializes a new";
$x = 1;
testlocal();

正如 testlocal 评论中提到的,声明“local $x;” 意味着 $x 现在是 undef

#!/usr/bin/perl

sub foo { print ", x is $x\n"; }

sub testdefault { $x++; foo(); }        # prints 2

sub testmy { my $x; $x++; foo(); }       # prints 1

sub testlocal { local $x = 2; foo(); }    # prints 2. new set mandatory


print "Default, everything is global";
$x = 1;
testdefault();

print "My does not affect function calls outside";
$x = 1;
testmy();

print "local is everything after this but initializes a new";
$x = 1;
testlocal();

As mentioned in testlocal comment, declaring "local $x;" means that $x is now undef

拧巴小姐 2024-07-12 21:25:54

简而言之,my 在词法作用域中将变量标记为私有,而 local 在动态作用域中将变量标记为私有。

更容易理解 my,因为它创建了通常意义上的局部变量。 创建了一个新变量,并且只能在封闭的词法块内访问它,该词法块通常用花括号标记。 大括号规则有一些例外,例如:

foreach my $x (@foo) { print "$x\n"; }

但这只是 Perl 做你的意思。 通常情况下,您会遇到这样的情况:

sub Foo {
   my $x = shift;

   print "$x\n";
}

在这种情况下,$x 是子例程私有的,并且其范围由大括号括起来。 需要注意的是,与 local 不同的是,my 变量的范围是根据文件中写入的代码定义的。 这是一个编译时现象。

要理解本地,您需要考虑程序运行时的调用堆栈。 当变量是 local 时,它会从对堆栈上低于该变量的所有内容执行 local 语句的位置开始重新定义,直到将堆栈返回给调用者包含local的块的。

一开始这可能会令人困惑,所以请考虑以下示例。

sub foo { print "$x\n"; }
sub bar { local $x; $x = 2; foo(); }

$x = 1;
foo(); # prints '1'
bar(); # prints '2' because $x was localed in bar
foo(); # prints '1' again because local from foo is no longer in effect

foo第一次被调用时,它看到$x的全局值是1。当bar被调用并且local时$x 运行,重新定义堆栈上的全局 $x。 现在,当从 bar 调用 foo 时,它会看到 $x 的新值 2。 到目前为止,这并不是很特别,因为如果不调用 local 也会发生同样的事情。 神奇的是,当 bar 返回时,我们退出由 local $x 创建的动态作用域,并且之前的全局 $x 返回到作用域。 因此,对于 foo 的最终调用,$x 为 1。

您几乎总是想使用 my,因为这为您提供了局部变量您正在寻找。 千载难逢,local 确实可以方便地做一些很酷的事情。

The short answer is that my marks a variable as private in a lexical scope, and local marks a variable as private in a dynamic scope.

It's easier to understand my, since that creates a local variable in the usual sense. There is a new variable created and it's accessible only within the enclosing lexical block, which is usually marked by curly braces. There are some exceptions to the curly-brace rule, such as:

foreach my $x (@foo) { print "$x\n"; }

But that's just Perl doing what you mean. Normally you have something like this:

sub Foo {
   my $x = shift;

   print "$x\n";
}

In that case, $x is private to the subroutine and its scope is enclosed by the curly braces. The thing to note, and this is the contrast to local, is that the scope of a my variable is defined with respect to your code as it is written in the file. It's a compile-time phenomenon.

To understand local, you need to think in terms of the calling stack of your program as it is running. When a variable is local, it is redefined from the point at which the local statement executes for everything below that on the stack, until you return back up the stack to the caller of the block containing the local.

This can be confusing at first, so consider the following example.

sub foo { print "$x\n"; }
sub bar { local $x; $x = 2; foo(); }

$x = 1;
foo(); # prints '1'
bar(); # prints '2' because $x was localed in bar
foo(); # prints '1' again because local from foo is no longer in effect

When foo is called the first time, it sees the global value of $x which is 1. When bar is called and local $x runs, that redefines the global $x on the stack. Now when foo is called from bar, it sees the new value of 2 for $x. So far that isn't very special, because the same thing would have happened without the call to local. The magic is that when bar returns we exit the dynamic scope created by local $x and the previous global $x comes back into scope. So for the final call of foo, $x is 1.

You will almost always want to use my, since that gives you the local variable you're looking for. Once in a blue moon, local is really handy to do cool things.

(り薆情海 2024-07-12 21:25:54

动态范围界定。 这是一个简洁的概念。 很多人不使用它,也不理解它。

基本上可以将 my 视为创建一个变量并将其锚定到一个 {} 块(又称作用域)。

my $foo if (true); # $foo lives and dies within the if statement.

所以 my 变量就是您所习惯的。 而使用动态作用域 $var 可以在任何地方声明并在任何地方使用。
因此,使用local,您基本上暂停了该全局变量的使用,并使用“本地值”来处理它。 因此 local 为临时变量创建一个临时作用域。

$var = 4;
print $var, "\n";
&hello;
print $var, "\n";

# subroutines
sub hello {
     local $var = 10;
     print $var, "\n";
     &gogo; # calling subroutine gogo
     print $var, "\n";
}
sub gogo {
     $var ++;
}

这应该打印:

4
10
11
4

Dynamic Scoping. It is a neat concept. Many people don't use it, or understand it.

Basically think of my as creating and anchoring a variable to one block of {}, A.K.A. scope.

my $foo if (true); # $foo lives and dies within the if statement.

So a my variable is what you are used to. whereas with dynamic scoping $var can be declared anywhere and used anywhere.
So with local you basically suspend the use of that global variable, and use a "local value" to work with it. So local creates a temporary scope for a temporary variable.

$var = 4;
print $var, "\n";
&hello;
print $var, "\n";

# subroutines
sub hello {
     local $var = 10;
     print $var, "\n";
     &gogo; # calling subroutine gogo
     print $var, "\n";
}
sub gogo {
     $var ++;
}

This should print:

4
10
11
4
懒的傷心 2024-07-12 21:25:54

引用自学习Perl

但是 local 的名称是错误的,或者至少是误导性的名称。 我们的朋友 Chip Salzenberg 说,如果他有机会乘坐时光机回到 1986 年并给 Larry 一个建议,他会告诉 Larry 用“save”这个名字来拨打本地电话。 [14] 这是因为 local 实际上会将给定的全局变量的值保存起来,因此稍后它会自动恢复到全局变量中。 (没错:这些所谓的“局部”变量实际上是全局变量!)这种保存和恢复机制与我们已经见过两次的机制相同,一次是在 foreach 循环的控制变量中,另一次是在 @_ 中。子程序参数数组。

因此,local 保存全局变量的当前值,然后将其设置为某种形式的空值。 您经常会看到它用于读取整个文件,而不是仅引导一行:

my $file_content;
{
    local $/;
    open IN, "foo.txt";
    $file_content = <IN>;
} 

调用 local $/ 将输入记录分隔符(Perl 停止读取“行”的值)设置为空值,导致 spaceship 运算符读取整个文件,因此它永远不会命中输入记录分隔符。

Quoting from Learning Perl:

But local is misnamed, or at least misleadingly named. Our friend Chip Salzenberg says that if he ever gets a chance to go back in a time machine to 1986 and give Larry one piece of advice, he'd tell Larry to call local by the name "save" instead.[14] That's because local actually will save the given global variable's value away, so it will later automatically be restored to the global variable. (That's right: these so-called "local" variables are actually globals!) This save-and-restore mechanism is the same one we've already seen twice now, in the control variable of a foreach loop, and in the @_ array of subroutine parameters.

So, local saves a global variable's current value and then set it to some form of empty value. You'll often see it used to slurp an entire file, rather than leading just a line:

my $file_content;
{
    local $/;
    open IN, "foo.txt";
    $file_content = <IN>;
} 

Calling local $/ sets the input record separator (the value that Perl stops reading a "line" at) to an empty value, causing the spaceship operator to read the entire file, so it never hits the input record separator.

一页 2024-07-12 21:25:54

我不敢相信没有人链接到 Mark Jason Dominus 关于这一问题的详尽论文:

I can’t believe no one has linked to Mark Jason Dominus’ exhaustive treatises on the matter:

生活了然无味 2024-07-12 21:25:54

http://perldoc.perl.org/perlsub.html#私有变量-via-my()

与创建的动态变量不同
局部运算符、词法变量
用 my 声明是完全隐藏的
来自外界,包括任何
称为子程序。 这是真的,如果
这是从以下位置调用的同一个子例程
本身或其他地方——每次调用都会得到
它自己的副本。

http://perldoc.perl.org/perlsub.html#临时值via-local()

本地修改其列出的变量
对于封闭块来说是“本地的”,
eval,或做 FILE——以及任何
从内部调用的子例程
堵塞。 当地人只是暂时提供
全局值(意思是包)
变量。 它不会创建本地
多变的。 这就是所谓的动态
范围界定。 词法范围是通过
my,它的工作方式更像是 C 的 auto
声明。

我认为这根本不清楚,除了说“本地到封闭块”之外,它的意思是当块退出时恢复原始值。

http://perldoc.perl.org/perlsub.html#Private-Variables-via-my()

Unlike dynamic variables created by
the local operator, lexical variables
declared with my are totally hidden
from the outside world, including any
called subroutines. This is true if
it's the same subroutine called from
itself or elsewhere--every call gets
its own copy.

http://perldoc.perl.org/perlsub.html#Temporary-Values-via-local()

A local modifies its listed variables
to be "local" to the enclosing block,
eval, or do FILE --and to any
subroutine called from within that
block. A local just gives temporary
values to global (meaning package)
variables. It does not create a local
variable. This is known as dynamic
scoping. Lexical scoping is done with
my, which works more like C's auto
declarations.

I don't think this is at all unclear, other than to say that by "local to the enclosing block", what it means is that the original value is restored when the block is exited.

浪漫之都 2024-07-12 21:25:54

谷歌在这方面确实很适合你:http://www.perlmonks.org/?node_id=94007

来自链接:

快速摘要:“我的”创建了一个新的
变量,'local'临时修改
变量的值。

即“本地”暂时更改
变量的值
,但仅
在它存在的范围内

通常使用 my,它更快并且不会做任何奇怪的事情。

Well Google really works for you on this one: http://www.perlmonks.org/?node_id=94007

From the link:

Quick summary: 'my' creates a new
variable, 'local' temporarily amends
the value of a variable.

ie, 'local' temporarily changes the
value of the variable
, but only
within the scope it exists in.

Generally use my, it's faster and doesn't do anything kind of weird.

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