📜 ⬆️ ⬇️

Perl 6 Lexical Variables

One of the problems of programming is the struggle with the increasing complexity of programs with increasing their size. Historically, it is solved by isolating certain parts of programs whose interaction with each other is limited. This approach operates at all levels of programming - “separation of concepts”, “do one thing and do it well”, BCNF, monads, procedures, classes, roles, modules. All of them encourage limiting parts of the program in order not to play against combinatorics. The simplest example of logical division is the lexical variable.

{ my $var; # $var   } # $var    


What's so interesting about it?

From the very beginning, Perl did this incorrectly. By default, the scope of variables in Perl 5 is a module variable, something like a global variable. If you define something inside the block, it will be visible from the outside.
')
 $ perl -v This is perl 5, version 12, subversion 1 (v5.12.1) $ perl -E '{ $var = 42 }; say $var' 42 $ perl -wE '{ my $var= 42 }; say $var' Name "main::var" used only once: possible typo at -e line 1. Use of uninitialized value $var in say at -e line 1. 


In Perl 6, lexical variables work by default.

 $ perl6 -e '{ $var = 42 }; say $var' #    'my' ===SORRY!=== Symbol '$var' not predeclared in <anonymous> $ perl6 -e '{ my $var = 42 }; say $var' #    –    ===SORRY!=== Symbol '$var' not predeclared in <anonymous> 


Well, well, maybe it will help to catch a typo ... But the main advantage of this is that you will work with honest scopes of variables. And this will allow you to manage the complexity of the programs.

Of course, Perl 5 did not force you to program "correctly" and did not impose the use of strict and warnings. Perl 5 promised to provide backward compatibility, and Perl 1 was clearly not designed to write complex programs. Global variables in small scripts make sense.

Perl 6 is trying to help you get started small and add structuring support as your programs grow. In the case of variables, this means that variables and variables are lexical by default in scripts and modules, but global variables remain in one-liners called by -e.

If you thought that about lexical variables, everything is not so. There are unexpected bonuses in this approach. Consider the function:

 sub counter($start_value) { my $count = $start_value; return { $count++ }; } 


A code block is returned. Each time we call counter, we get a piece of code that can be called the number of times needed.

This is what happens if we create two different pieces of this code and play with them:

 my $c1 = counter(5); say $c1(); # 5 say $c1(); # 6 my $c2 = counter(42); say $c2(); # 42 say $c1(); # 7 say $c2(); # 43 


Do you see? $ c1 and $ c2 work independently. Everyone is saved as a variable $ count. For us, it may look like one variable, but for two different counter instances, these are two different areas for storing values ​​— since, each time we re-enter a block, we open a new scope. Such a unit is called a closure.

If it seemed to you that closures are similar to lightweight objects - congratulations, this is exactly so. Their essence of access restrictions is the same as that of encapsulation and information hiding in OO. This is all necessary to limit the field of activity so that parts of the program can do as little as possible.

Source: https://habr.com/ru/post/253133/


All Articles