|
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
$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 5Perl 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 scopeA 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 5When 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 scopeNote 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(); # 3What 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 exitThis 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
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
|
|
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 |
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!!
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.
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.
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
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!
Introducing the media solution for total action without interruption. TRY IT NOW FOR FREE!