Initially, all variables in Perl were global: there could be only one variable with the same name and type. Undeclared variables are global.

In Perl 4, a variable can be declared local with the local variable declaration statement. This creates a new variable, that is used and modified separately from any pre-existing variable of the same name, which will continue to happen until execution leaves the scope in which it was declared. This means the uses of the variable are determined by the execution path of the code, a mechanism known as dynamic scope. After the variable goes out of scope, the previous one (if any) becomes effective again.

Perl 5 introduced the my variable declaration. It defines a lexically scoped variable: one of which the uses are those that occur within the same block of code. The name derives from the fact that we can just look at the code blocks, instead of having to follow the execution path, to find the uses of the variable.

This example program was stolen from James Riely's lecture notes:


$x = 0;          # binding, global                                      
$y = 0;          # binding, global
                                   
sub foo {                                                               
  $x++; $y++;    # dynamically bound                                    
}                                                                       

sub printxy {                                                           
  print "x=$x y=$y"; # dynamically bound                                
}                                                                       

{                                                                       
  local $x = 10; # binding, dynamically scoped (seen by callees)        
  my    $y = 10; # binding, lexically scoped (private)                  
  foo ();                                                               
  printxy();                                                            
}                                                                       

It prints x=11 y=1.

Common Lisp is another example of a language with both lexically and dynamically scoped variables.

In Perl 5.6, yet another flavour was added: the our keyword defines a variable that is known everywhere in its package (i.e. module or class) but not to other packages. A typical example is the $VERSION variable that packages traditionally use to record their version number.