perl中的局部变量和全局变量

时间:2022-06-03 09:08:08

I am having few doubts for local/our scope in perl. I read lot of documentation but still confusion is there. Following are the confusions

我对perl中的本地/我们的范围几乎没有疑问。我阅读了很多文档,但仍然存在混淆。以下是混乱

  1. What is local scope?

    什么是当地范围?

    what I read is -> local copies the value of global variable, change the value, user will use it and outside the block it will retain the global value

    我读的是 - >本地复制全局变量的值,更改值,用户将使用它和块外它将保留全局值

    Confusion -> my does the same thing. Only benefit I see is that some variables like $package::var cannot be declared with my scope but can be declared with local scope. What else for local

    困惑 - >我做同样的事情。我看到的唯一好处是像$ package :: var这样的变量不能用我的作用域声明,但可以用本地作用域声明。还有什么适合当地的

  2. What is "global" variable?

    什么是“全球”变量?

What is read is -> Its scope is within the package. Basically we put the global variable in @EXPORT array and use it or append the namespace with it to use in other packages.

读到的是 - >它的范围在包内。基本上我们将全局变量放在@EXPORT数组中并使用它或附加名称空间以在其他包中使用。

doubt -> Again if we declare variable with my scope in main only then we can access the variable throughout the package. Is that right? Is it possible to add the my scoped variables in @EXPORT array and use it in another packages?

怀疑 - >再次,如果我们在main中使用我的范围声明变量,那么我们可以在整个包中访问变量。是对的吗?是否可以在@EXPORT数组中添加我的范围变量并在另一个包中使用它?

I think global variables are declared with our keyword. Is there any other way to do so?

我认为全局变量是用我们的关键字声明的。有没有其他方法可以这样做?

This question may look like repetitive but i am confused

这个问题可能看起来像重复但我很困惑

3 个解决方案

#1


17  

In terms of scoping, there are two kinds of variables in Perl.

在范围界定方面,Perl中有两种变量。

  • Lexical variables are lexically scoped, which means they are only visible in the current lexical scope.
  • 词汇变量是词法范围的,这意味着它们仅在当前词法范围内可见。
  • Package variables are globally scoped, which means they are visible by all code in the interpreter.
  • 包变量是全局范围的,这意味着解释器中的所有代码都可以看到它们。

Here are ways to create variable.

以下是创建变量的方法。

  • my creates a lexical variable.
  • 我创建了一个词法变量。
  • our creates a lexical variable that is aliased to the variable of the same name in the current package. In other words, our $foo; is the same as alias my $foo = $The::Current::Package::foo;.
  • 我们创建一个词法变量,该变量别名为当前包中同名变量。换句话说,我们的$ foo;与别名我的$ foo = $ The :: Current :: Package :: foo;相同。
  • Global variables are created on use.
  • 全局变量是在使用时创建的。

local doesn't create any variables. It simply backs up a variable until the current lexical scope is destroyed.

local不会创建任何变量。它只是备份一个变量,直到当前的词法范围被破坏。


my does the same thing.

我做了同样的事情。

No. local does not change the scope of a variable. While a lexical variable is only visible in a lexical scope, a localized global variable is still visible across the entire interpreter.

编号本地不会改变变量的范围。虽然词法变量仅在词法范围内可见,但是整个解释器仍然可以看到本地化的全局变量。

$x = 123;
sub foo { print "$x\n"; }
{ local $x = 456; foo(); }  # 456
foo();                      # 123

$x = 123;
sub foo { print "$x\n"; }
{ my $x = 456; foo(); }   # 123
foo();                    # 123

What else for local

还有什么适合当地的

local is primarily used to approximate the functionality of my for variables that cannot otherwise be declared lexically.

local主要用于近似我的变量的功能,否则无法以词法方式声明。

(Historically, that was all variables. Since 5.6, only punctuation variables cannot be declared lexically.)

(从历史上看,这就是所有变量。从5.6开始,只能在词法上声明标点符号变量。)


What is "global" variable?

什么是“全球”变量?

A variable that can seen globally, i.e. by any code in the interpreter.

可以全局看到的变量,即解释器中的任何代码。


Is it possible to add the my scoped variables in @EXPORT array and use it in another packages?

是否可以在@EXPORT数组中添加我的范围变量并在另一个包中使用它?

No. @EXPORT is used by Exporter. Exporter would not be able to find anything but global symbols (since files are compiled in fresh lexical scopes), so @EXPORT must only contain global symbols.

号码@EXPORT由Exporter使用。除了全局符号之外,导出器将无法找到任何内容(因为文件是在新的词法范围中编译的),因此@EXPORT必须只包含全局符号。

#2


5  

There are two kinds of variables, lexically scoped and globally scoped.

有两种变量,词法范围和全局范围。

In Perl before version 5, there was only globally scoped. These variables are the package variables. These variables are available everywhere in the program if you use the package prefix.

在版本5之前的Perl中,只有全局作用域。这些变量是包变量。如果使用包前缀,这些变量可在程序中的任何位置使用。

The local keyword was introduced to provide a way to alter the value of one of these package global variables inside a limited scope, such as inside one subroutine. It will save the old value on a stack when entering the scope with the local statement, and upon exiting, it will restore the old value. These are still package globals, which means that they are still available everywhere. If you are inside a scope with a local variable, and you call a subroutine, that variable is still visible inside that subroutine.

引入local关键字是为了提供一种在有限范围内更改其中一个包全局变量的值的方法,例如在一个子例程中。当使用本地语句输入作用域时,它将在堆栈上保存旧值,并在退出时,它将恢复旧值。这些仍然是包全局变量,这意味着它们仍然可以在任何地方使用。如果您在具有局部变量的范围内,并且调用子例程,则该子例程内的该变量仍然可见。

The my keyword was introduced in version 5, and provides lexically scoped variables. These variables only exist inside the scope where they are declared. This means that if you call a subroutine, that my variable is not visible. Upon exiting a scope, the my variables simply go away. You should prefer to use my variables when possible, because you do not want your variables to be visible inside subroutines that you call. You cannot use these type of variables in the @EXPORT list because these variables are not visible outside of their scope.

my关键字是在版本5中引入的,它提供了词法范围的变量。这些变量仅存在于声明它们的范围内。这意味着如果你调用子程序,那我的变量是不可见的。退出范围后,我的变量就会消失。您应该尽可能使用我的变量,因为您不希望变量在您调用的子例程中可见。您不能在@EXPORT列表中使用这些类型的变量,因为这些变量在其范围之外是不可见的。

Finally, the our keyword is a combination of both, in that it gives you a variable that is a package global, but that variable is lexically scoped. This means it will be available anywhere in the program, but at the end of the enclosing block, you cannot refer to that variable any more.

最后,我们的关键字是两者的组合,因为它为您提供了一个包全局变量,但该变量是词法范围的。这意味着它将在程序中的任何位置可用,但在封闭块的末尾,您不能再引用该变量。

#3


5  

Example 1:

sub mess_with_foo {
      $foo=0;
 }

 sub myfunc {
      my $foo=20;
      mess_with_foo();
      print $foo;
 }
 myfunc();

Example 2:

 sub mess_with_foo {
      $foo=0;
 }

 sub myfunc {
      local $foo=20;
      mess_with_foo();
      print $foo;
 }
 myfunc();

Example 1 prints 20 because mess_with_foo() could not see my $foo. It could not change it. my $foo can only be seen in its scope of myfunc().

示例1打印20因为mess_with_foo()无法看到我的$ foo。它无法改变它。我的$ foo只能在myfunc()的范围内看到。

Example 2 prints 0 because mess_with_foo() can see my $foo and change it. local $foo can be seen in its scope of myfunc() AND in the scope of any function called from within its scope of myfunc().

示例2打印0,因为mess_with_foo()可以看到我的$ foo并更改它。本地$ foo可以在myfunc()的范围内看到,并且在myfunc()范围内调用的任何函数的范围内都可以看到。

That's the only difference. Neither my $foo nor local $foo will be seen outside of their scope of myfunc().

这是唯一的区别。我的$ foo和本地$ foo都不会在myfunc()范围之外被看到。

#1


17  

In terms of scoping, there are two kinds of variables in Perl.

在范围界定方面,Perl中有两种变量。

  • Lexical variables are lexically scoped, which means they are only visible in the current lexical scope.
  • 词汇变量是词法范围的,这意味着它们仅在当前词法范围内可见。
  • Package variables are globally scoped, which means they are visible by all code in the interpreter.
  • 包变量是全局范围的,这意味着解释器中的所有代码都可以看到它们。

Here are ways to create variable.

以下是创建变量的方法。

  • my creates a lexical variable.
  • 我创建了一个词法变量。
  • our creates a lexical variable that is aliased to the variable of the same name in the current package. In other words, our $foo; is the same as alias my $foo = $The::Current::Package::foo;.
  • 我们创建一个词法变量,该变量别名为当前包中同名变量。换句话说,我们的$ foo;与别名我的$ foo = $ The :: Current :: Package :: foo;相同。
  • Global variables are created on use.
  • 全局变量是在使用时创建的。

local doesn't create any variables. It simply backs up a variable until the current lexical scope is destroyed.

local不会创建任何变量。它只是备份一个变量,直到当前的词法范围被破坏。


my does the same thing.

我做了同样的事情。

No. local does not change the scope of a variable. While a lexical variable is only visible in a lexical scope, a localized global variable is still visible across the entire interpreter.

编号本地不会改变变量的范围。虽然词法变量仅在词法范围内可见,但是整个解释器仍然可以看到本地化的全局变量。

$x = 123;
sub foo { print "$x\n"; }
{ local $x = 456; foo(); }  # 456
foo();                      # 123

$x = 123;
sub foo { print "$x\n"; }
{ my $x = 456; foo(); }   # 123
foo();                    # 123

What else for local

还有什么适合当地的

local is primarily used to approximate the functionality of my for variables that cannot otherwise be declared lexically.

local主要用于近似我的变量的功能,否则无法以词法方式声明。

(Historically, that was all variables. Since 5.6, only punctuation variables cannot be declared lexically.)

(从历史上看,这就是所有变量。从5.6开始,只能在词法上声明标点符号变量。)


What is "global" variable?

什么是“全球”变量?

A variable that can seen globally, i.e. by any code in the interpreter.

可以全局看到的变量,即解释器中的任何代码。


Is it possible to add the my scoped variables in @EXPORT array and use it in another packages?

是否可以在@EXPORT数组中添加我的范围变量并在另一个包中使用它?

No. @EXPORT is used by Exporter. Exporter would not be able to find anything but global symbols (since files are compiled in fresh lexical scopes), so @EXPORT must only contain global symbols.

号码@EXPORT由Exporter使用。除了全局符号之外,导出器将无法找到任何内容(因为文件是在新的词法范围中编译的),因此@EXPORT必须只包含全局符号。

#2


5  

There are two kinds of variables, lexically scoped and globally scoped.

有两种变量,词法范围和全局范围。

In Perl before version 5, there was only globally scoped. These variables are the package variables. These variables are available everywhere in the program if you use the package prefix.

在版本5之前的Perl中,只有全局作用域。这些变量是包变量。如果使用包前缀,这些变量可在程序中的任何位置使用。

The local keyword was introduced to provide a way to alter the value of one of these package global variables inside a limited scope, such as inside one subroutine. It will save the old value on a stack when entering the scope with the local statement, and upon exiting, it will restore the old value. These are still package globals, which means that they are still available everywhere. If you are inside a scope with a local variable, and you call a subroutine, that variable is still visible inside that subroutine.

引入local关键字是为了提供一种在有限范围内更改其中一个包全局变量的值的方法,例如在一个子例程中。当使用本地语句输入作用域时,它将在堆栈上保存旧值,并在退出时,它将恢复旧值。这些仍然是包全局变量,这意味着它们仍然可以在任何地方使用。如果您在具有局部变量的范围内,并且调用子例程,则该子例程内的该变量仍然可见。

The my keyword was introduced in version 5, and provides lexically scoped variables. These variables only exist inside the scope where they are declared. This means that if you call a subroutine, that my variable is not visible. Upon exiting a scope, the my variables simply go away. You should prefer to use my variables when possible, because you do not want your variables to be visible inside subroutines that you call. You cannot use these type of variables in the @EXPORT list because these variables are not visible outside of their scope.

my关键字是在版本5中引入的,它提供了词法范围的变量。这些变量仅存在于声明它们的范围内。这意味着如果你调用子程序,那我的变量是不可见的。退出范围后,我的变量就会消失。您应该尽可能使用我的变量,因为您不希望变量在您调用的子例程中可见。您不能在@EXPORT列表中使用这些类型的变量,因为这些变量在其范围之外是不可见的。

Finally, the our keyword is a combination of both, in that it gives you a variable that is a package global, but that variable is lexically scoped. This means it will be available anywhere in the program, but at the end of the enclosing block, you cannot refer to that variable any more.

最后,我们的关键字是两者的组合,因为它为您提供了一个包全局变量,但该变量是词法范围的。这意味着它将在程序中的任何位置可用,但在封闭块的末尾,您不能再引用该变量。

#3


5  

Example 1:

sub mess_with_foo {
      $foo=0;
 }

 sub myfunc {
      my $foo=20;
      mess_with_foo();
      print $foo;
 }
 myfunc();

Example 2:

 sub mess_with_foo {
      $foo=0;
 }

 sub myfunc {
      local $foo=20;
      mess_with_foo();
      print $foo;
 }
 myfunc();

Example 1 prints 20 because mess_with_foo() could not see my $foo. It could not change it. my $foo can only be seen in its scope of myfunc().

示例1打印20因为mess_with_foo()无法看到我的$ foo。它无法改变它。我的$ foo只能在myfunc()的范围内看到。

Example 2 prints 0 because mess_with_foo() can see my $foo and change it. local $foo can be seen in its scope of myfunc() AND in the scope of any function called from within its scope of myfunc().

示例2打印0,因为mess_with_foo()可以看到我的$ foo并更改它。本地$ foo可以在myfunc()的范围内看到,并且在myfunc()范围内调用的任何函数的范围内都可以看到。

That's the only difference. Neither my $foo nor local $foo will be seen outside of their scope of myfunc().

这是唯一的区别。我的$ foo和本地$ foo都不会在myfunc()范围之外被看到。