18. Global, private, local variables
1. Global versus private
In Perl, global variables are accessible from anywhere in the program, while private variables are restricted in scope, typically to a specific lexical scope or within a package. The disadvantages of global variables are well-known:
- Global variables have a global scope, meaning they can be accessed from anywhere in the program.
- Global variables can be accessed and modified by any part of the program.
- Global variables are prone to name collisions, especially in larger programs with many modules.
Better: private variables. These variables, by being confined to a specific scope or package, help avoid name collisions and promote modularization.In Perl, you can create private variables using lexical scoping and the
my keyword.
$name = "Reinier"; # without my, so a global variable
sub f1 {
my $name = "Sebastian";
print("Function f1: $name\n");
}
sub f2 {
my $name = "Daniel";
print("Function f2: $name\n");
}
sub f3 {
$name = "Florence"; # without my
print("Function f3: $name\n");
}
print("Global: $name\n"); # Reinier
f1(); # Sebastian
print("Global: $name\n"); # Reinier
f2(); # Daniel
print("Global: $name\n"); # Reinier
f3(); # Florence
print("Modified global: $name\n"); # Florence
2. Privat variables and accessor functionsIn this example,
$private_var is only accessible within the lexical scope of the block where it's defined. However, you can provide access to it using accessor functions like
get_private_var and
set_private_var, which are also defined within the same scope.
{
my $private_var = "This is a private variable";
sub get_private_var {
return $private_var;
}
sub set_private_var {
my ($value) = @_;
$private_var = $value;
}
}
# Outside of the block, you cannot access $private_var directly
# But you can use the accessor functions:
print get_private_var(); # Output: This is a private variable
set_private_var("New value");
print get_private_var(); # Output: New value
3. my versus localIn Perl, my and local are both used to declare lexical variables, but they have different scopes and behaviors:
my:
- Declares a new variable that is lexically scoped to the enclosing block or file.
- The variable is private to the current scope and any nested scopes within it.
- my variables are not visible outside of the block or file in which they are declared.
- When a new scope is entered, any existing my variable with the same name is shadowed, and a new variable of the same name is created.
local:
- Creates a localized dynamic scope for a global variable.
- Temporarily changes the value of a global variable within the current scope and any subroutines called from that scope.
- Unlike my, local does not create a new variable; it only temporarily alters the value of an existing global variable.
- The original value of the global variable is restored when the scope exits.
In the next example,
$x is declared with my inside a subroutine, making it only accessible within that subroutine. On the other hand,
$y is declared outside of any subroutine and then localized inside
example_with_local, temporarily changing its value within the scope of that subroutine.
# Using my
sub example_with_my {
my $x = 10;
print "Inside: $x\n"; # Output: Inside: 10
}
# Using local
$y = 20;
sub example_with_local {
local $y = 30;
print "Inside: $y\n";# Output: Inside: 30
}
print "Before my: $x\n"; # This will result in an error because $x is not accessible here
example_with_my(); # Output: 10
print "After my: $x\n"; # This will result in an error because $x is not accessible here
print "Before local: $y\n"; # Output: Before local: 20
example_with_local(); # Output: 30
print "After local: $y\n"; # Output: After local: 20