Programmers Heaven jobs
Hardware Embedded Software Engineer
Backend Website Programmer - DotNetNuke
Network Programmer


More jobs                Post a job


Perl6 FAQ - Variables And Scoping

This FAQ is part of the Programmer's Heaven Perl 6 FAQ. It answers questions about different types of variable and scoping in Perl 6.

What are sigils, and how does the use of sigils differ between Perl 5 and Perl 6?

Sigils in both Perl 5 and Perl 6 specify the basic structural type of a variable. Examples of structural types are:

  • Scalars - single items
  • Arrays - indexed by an integer
  • Hashes - key/value pairings
A sigil is a single character that comes before the name of the variable.

$monkey         # scalar
@monkeys        # array
%monkey_ages    # hash, e.g. key is name, value is age


In Perl 6, the sigil always corresponds to the structural type of that variable. This differs from Perl 5, where you used the sigil representing the type of variable you were expecting to retrieve from a data structure.

@monkeys[5]            # Perl 6
$monkeys[5]            # Perl 5
%monkey_ages{'Bozo'}   # Perl 6
$monkey_ages{'Bozo'}   # Perl 5


Perl 6 also introduces secondary sigils. These specify the scope of the variable and are often not required. For example, the global secondary sigil (or "twigil") is "*". The environment variables for a program are global, so they are placed in the global hash "%*ENV".

What is a lexical variable?

A lexical variable exists only in a given scope, where a scope generally is defined as an area between a pair of curly braces. They are somewhat like local variables in other languages. In Perl 6, as in Perl 5, lexicals are introduced with the "my" keyword.

if $x == 5 {
    my $y = 2;
    ...
}
# $y does not exist here - out of scope


A lexical variable cannot be seen outside of the scope that it was declared in. Lexical variables in deeper nested scopes will mask the visibility of those in outer scopes.

my $x = 5;
if 1 == 1 { # Always true
    my $x = 10;
    say $x; # Prints 10
}
say $x; # Prints 5


When Perl 6 is trying to locate a lexical variable, it will not look at the the lexicals of the subroutine that called it.

sub test() {
    print $x; # Error
}
my $x = 42;
test();


However, if one subroutine is textually enclosed inside another, lexicals that are declared in the enclosing subroutine will be visible, so this example will print 42:

sub outer() {
    my $x = 42;
    sub inner() {
        say $x;
    }
    inner();
}
outer();


(Note: The main body of the program could be considered a subroutine; therefore, if you put the declaration of $x before the sub in the "sub test()" example, the program will run. Do not be confused by this - lexicals are statically scoped.)

What is a package variable?

A package variable is one that exists in a given package (more commonly known as namespace) and is visible from outside of that package if the name of the package is put first.

One way to introduce a new package (or namespace) in Perl 6 is to use the "module" keyword (which partially replaces the "package" keyword in Perl 5). Modules are useful for grouping together related subroutines. Package variables are then declared with the "our" keyword, just as they were in Perl 5.

module Test {
    our $x = 42;
}
say $Test::x; # Prints 42
say $x;       # Error - no $x in scope


Note here the use of "::" as the package separator.

What is a state variable?

A state variable is like a lexical variable, but it remembers its value between entries to the scope. These did not exist in Perl 5, but are like static variables that have appeared in other languages. You assign to a state variable when declaring it, but this assignment only happens the first time the scope is entered.

sub counter() {
    state $n = 0;
    $n++;
    return $n;
}
say counter(); # 1
say counter(); # 2
say counter(); # 3


What is a temporary (temp) variable?

Declaring a variable with temp will (at least conceptually) make a copy of the variable with that name in the enclosing scope. This means that modifications to the variable will not last beyond the scope it is made temporary within.

my $x = 5;
if 1 == 1 {
    temp $x;
    say $x;   # 5 - taken value of outer $x
    $x++;
    say $x;   # 6 - incremented value
}
say $x;       # 5 - original value restored on scope exit


This is useful when you need to temporarily override the value of a variable, but need it to be restored to its original value when you leave the current scope. It is all to easy to forget to restore the copy yourself if you implement this manually.

What is a hypothetical (let) variable?

Hypothetical variables are very much like temp variables, apart from the original value of the variable is only restored if the block "fails". For a block to fail it needs to either throw an exception or return an undefined value. Values that are defined but would be considered false (for example, 0 or the empty list) will not cause the block to fail. Here is an example.

sub feed($food) {
    # hypothetically, I will be happy after being fed
    let $state = 'happy';
    # ...but certain things may stop me becoming happy
    if $food eq 'squid' {
        fail;
    }
    # If we get here, return 1 (= success)
    return 1;
}
our $state = 'sad';
feed('squid');
say $state; # Still sad
feed('curry');
say $state; # Happy now
feed('squid');
say $state; # Still happy
Note that I'm still happy after the second attempt to feed me squid because $state was set to "happy" before the "let" statement, so even when "fail" is called it restores to "happy" again.

Hypothetical variables are useful for providing transaction-like "all or nothing" semantics, where you only want to change a set of variables if all changes are successful, and never leave some changed and some not because something half way into the changes threw an exception.

What is a global variable ($*)?

A twigil is a secondary sigil (the * in $*).
Global variables are visible throughout all packages and scopes in the program. To access a global variable, use the * twigil.

sub test() {
    say $*x;   # 42
    my $x = 5;
    say $x;    # 5 - refers to the lexical
    say $*y;   # 64 - goes direct to global
    say $y;    # Error (unless "use strict;" is not in force)
}
$*x = 42;
$*y = 64;
test();


What is binding (the ":=" and "::=" operators)?

Binding, a new feature in Perl 6, creates an alias to a variable (that is, another name for the same thing). The ":=" operator does this at run time (when the program is being executed), while "::=" does it at compile time (when the program is being compiled).

my $a = 5;
my $b := $a; # Create alias $b to $a
$b++;        # Increment $b
say $a;      # 6 - $a and $b same variable really


Aliases are useful in a number of situations, including ones where you have a very long package name for a variable and want a shorter lexical alias for it.

my $earth := $Universe::MilkyWay::SolarSystem::Earth;


Note that if an expression is bound using ::=

my $a ::= 39 + 3;


Then the value being bound to $a - in this case 39 + 3 - will be evaluated at compile time.

Where did all those crazy special variables like $$, $/, $! and so on go?

In general, they were renamed to things that you have more chance of remembering and anyone reading your code has more chance of guessing what means. For example, "$0" (the name of the current script) has become "$?FILE", the "?" twigil referring to things that are known from compile time.


Back To FAQ List | Next Section

What's next?




Join our Perl 6 Newsletter
Email:



Visit our Perl Resources * Perl 6 Forum * Perl, PHP & Python zone * Perl Programming Forum * Beginners Guide to Perl * Regex tutorial * 20 Perl Tips And Tricks




  User Comments


riya

From India
(Report as abusive)
"Very Useful"
this faqs made to know about many things unknown and it helped me a lot
  View all   Rate and comment this article




 
Printer friendly version of the Perl6-FAQ-Variables page


Sponsored links

ASP.NET 3.5 Hosting on Windows 2008!
ASP.NET 3.5/2.0 Hosting on Windows 2008 & 2003! AJAX, LINQ, & Silverlight Ready! 3 Mo. Free!!
Build IT Knowledge with Current & Trusted Content
Helps Employees Develop & Hone New Technical Programming Skills. Sign Up & Get Full Access.
Check Out IT Certification Preparation Materials
Sign Up With SkillSoft & Get Access to Training Materials for Over 50 Professional Certifications.
SFTP components for .NET
Add complete SSH and SFTP support to your .NET framework application
Experience Adobe? FLASH MEDIA SERVER 3
Introducing the media solution for total action without interruption. TRY IT NOW FOR FREE!


Newsletter | Submit Content | About | Advertising | Awards | Contact Us | Link to us |
© 1996-2008 Community Networks Ltd All rights reserved. Reproduction in whole or in part, in any form or medium without express written permission is prohibited. Violators of this policy may be subject to legal action. Please read Terms Of Use and Privacy Statement for more information. Development by Synchron Data - .NET development.