1. Perl
  2. scope

Understand Perl scope

Get a better understanding of Perl scope. This article is written on the assumption that the strict pragma is enabled, so please write the following at the beginning of the source code as usual.

use strict;
use warnings;

Create scope

Perl scope starts with "{" and ends with "}".

{
  # Scope
}

Meaning of scope

Lexical variable

Lexical variable declared within a scope (variable declared with my) can only be referenced within that scope. Also, the value contained in the variable is released when the scope ends.

{
  my $num = 1;

  # Can be referenced
  print $num;
}

# Cannot be referenced at this position
print $num;

Package variable

Package variable declared inside a scope (variable declared with our) can be referenced by partial name within that scope. You must use a fully qualified name to reference it from outside the scope.

package Foo;

{
  our $NUM = 1;

  # Can be referenced by part name
  print $NUM;
}

# Cannot be referenced by partial name
print $NUM;

# Can be referenced by fully qualified name
print $Foo::NUM;

Keep in mind that once a package variable is created, it exists to the end of the program and can be referenced by its fully qualified name from anywhere in the program.

Package variable modified locally

You can use local to temporarily change a package variable. This changed value is reverted at the end of the scope.

package Foo;

our $NUM = 1;

{
  local $NUM = 2;

  # 2 is output
  print $NUM;
}

# Return to 1 at this position
print $NUM;

Use local only for temporary changes to the value of a package variable, and don't use it for variable declarations as it used to be.

Subroutine

Perl subroutine are scope-independent.

{
  sub foo {
    ...
  }

  # Can be called
  foo ();
}

# Can be called
foo ();

When a subroutine is defined, it is registered in what is called a symbol table and can be called from any position in the program.

If you want the subroutine to have scope, assign an anonymous subroutine (which is the subroutine's reference) to a lexical variable.

{
  my $foo = sub {...};

  # Can be called
  $foo->();
}

# Cannot be called from this position
$foo->();

At the end of the scope, the subroutine reference assigned to $foo is released. Note that the subroutine itself is not freed. sub {...} is parsed and placed in memory at compile time.

Scope in if and while statement

The "{}" used in if statement and while statement is also a scope. In Perl, the scope is "{}", which is used in all kinds of syntax. It's consistent in this regard and is very straightforward compared to other languages.

if (condition) {
  # Scope
}

while (condition) {
  # Scope
}

eval {
  # Scope
};

sub {
  # Scope
}

(Reference) eval

Files also have one scope.

use strict;
use warnings;

# process

The above can be thought of as the beginning and end of the file surrounded by "{" and "}" as shown below.

{
  use strict;
  use warnings;

  # process
}

Lexical variable declared at special positions

There are some cases where you have a scope, though it is not declared inside the scope.

if condition part

The a lexical variable declared in the conditional part of if has the scope of if.

if (my $num = 1) {
  # Can be referenced
  print $num;
}

# Cannot be referenced at this position
print $num;

Since there is no scope for the postfixed if in the first place, it does not have a scope.

Statement if my $num = 1;

# Can be referenced
print $num;

The same is true for unless statement and while statement.

# unless
unless (my $num = 1) {
  # Can be referenced
  print $num;
}

# Cannot be referenced
print $num;
# while
while (my $num = 1) {
  # Can be referenced
  print $num;
}

# Cannot be referenced
print $num;

for condition part

The a lexical variable declared in the condition part of for has the scope of for.

for (my $i = 0; $i < @nums; $i++) {
  # Can be referenced
  print $i;
}

# Cannot be referenced
print $i;

variable assignment part of for

The a lexical variable declared in the variable assignment part of for has the scope of for.

for my $num (@nums) {
  # Can be referenced
  print $num;
}

# Cannot be referenced
print $num;

At the end

If you keep this in mind, you won't have any problems with Perl scope. You'll find that Perl scope is intuitive and straightforward. This has been very helpful in making the structure of Perl programs easier to see.

Related Informatrion