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 functions

In 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 local

In 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