代码改变世界

Method Calling in Perl

2014-09-10 22:00  i一骑绝尘  阅读(145)  评论(0编辑  收藏  举报

This is notes from reading the "object oriented perl programming".

Elements of the @_ array are special in that they are not copies of the actual arguments of the function call. Rather they are aliases for those arguments. That means that if values are assigned to $_[0], $_[1], $_[2], etc., each value is actually assigned to the corresponding argu- ment with which the current subroutine was invoked.  

sub cyclic_incr{  $_[0] = ($_[0]+1) % 10;} 
print $next_digit;# prints: 8  
cyclic_incr($next_digit); print $next_digit; # prints: 9  
cyclic_incr($next_digit); print $next_digit; # prints: 0  
Attempting to call such a subroutine with an unmodifiable value:	cyclic_incr(7);

This aliasing behavior is useful when you need it, but can introduce subtle bugs if youtrip it unintentionally. Therefore, if you don’t intend to change the values of the original ar- guments, it’s usually a good idea to explicitly copy the @_array into a set of variables, to avoid "accidents""  

sub next_cyclic{
    ($number,$modulus) = @_;		
    $number = ($number+1) % $modulus; 
    return $number;
}

When a subroutine is called, it’s possible to detect whether it was expected to return a scalar value, or a list, or nothing at all. These possibilities define three contexts in which a subroutine may be called.

We use Carp::carp subroutine, instead of the built-in warn function, so that the warning reports the location of the call to the subroutine, instead of the location within the subroutine at which the error was actually detected.

Subroutines can also be declared with a prototype, which is a series of specifiers that tells the compiler to restrict the type and number of arguments with which the subroutine may be invoked.  

sub insensitive_less_than ($$) {return lc($_[0]) lt lc($_[1]); 

The prototype is ($$) and specifies that the subroutine insensitive_less_than can only be called with exactly two arguments, each of which will be treated as a scalar—even if it’s actually an array!

Prototypes are only enforced when a subroutine is called using the name(args) syntax. Prototypes are not enforced when a subroutine is called with a leading & or through a subroutine reference (see References and referents below).

The ref function can be used to improve error messages, like,

die "Expected scalar reference" unless ref($slr_ref) eq "SCALAR";

or to allow a subroutine to automatically dereference any arguments that might be references: 

sub trace {	
    ($prefix, @args) = @_;    
    
    foreach $arg ( @args ) {		
        if (ref($arg) eq 'SCALAR')
            { print $prefix, ${$arg} } 		
        elsif (ref($arg) eq 'ARRAY')
            { print $prefix, @{$arg} }    		
        elsif (ref($arg) eq 'HASH')
            { print $prefix, %{$arg} }     		
        else{ print $prefix, $arg }	} 
}
            

The ref function has a vital additional role in object-oriented Perl, where it can be usedto identify the class to which a particular object belongs. 

@row1 = ( 1, 2, 3);
@row2 = ( 2, 4, 6);
@row3 = ( 3, 6, 9);
@cols = (\@row1,\@row2,\@row3);   
$table = \@cols;

This will create a multi-dimensional data structures.  

tables like this are very popular, so Perl provides some syntactic assistance. If we specify a list of values in square brackets instead of parentheses, the result is not a list, but a reference to a nameless (or anonymous) array. That array is automatically initialized to the specified values. Using this syntax we can replace the table set-up code with the following:

$row1_ref = [ 1, 2, 3]; 
$row2_ref = [ 2, 4, 6];   
$row3_ref = [ 3, 6, 9];   
$table = [$row1_ref, $row2_ref, $row3_ref];

Better still, we can eliminate the $row... variables entirely, by nesting sets of square brackets: 

my $table = [  [ 1, 2, 3],  [ 2, 4, 6],  [ 3, 6, 9],];

anonymous subroutines can be created by using the sub keyword without giving a subroutine name:

sub { print "Heeeeeeeeere's $_[0]!\n" };

Of course, by itself such a declaration is useless, since there’s no way of actually calling such a nameless subroutine. Fortunately, when sub is used in this way, it returns a reference to the anonymous subroutine it just created. If we cache that reference in a scalar:

$sub_ref = sub { print "Heeeeeeeeere's $_[0]!\n" };

we can then use it to call the original subroutine, via the arrow notation:

$sub_ref->("looking at you, kid");

The need for anonymous subroutines doesn’t crop up very often in regular Perl programming, but they are surprisingly useful in object-oriented Perl.  References also provide a means of passing unflattened arrays or hashes into subroutines.  Suppose we want to write a subroutine called insert, to insert a value into a sorted array of values, so that the ordering of the array is preserved.  

sub insert {
    ($arr_ref, $new_val) = @_;
    @{$arr_ref} = sort {$a<=>$b} (@{$arr_ref}, $new_val);# numerical sort
}
my @ordered = (1,3,4,7);
my $next_val = 5;
my @result = insert(\@ordered, $next_val);
print join(" ",@result);

 

By default, Perl assumes that code is written in the namespace of the main package, but you can change that default at any time using the package keyword. A package declaration changes the namespace until another package declaration is encountered, or until the end of the current enclosing block, eval, subroutine, or file. One type of variable is a lexical variable. Unlike package variables, lexicals have to be explicitly declared, using the my keyword. Lexical variables differ from package variables in three important respects:

• They don’t belong to any package, so you can’t prefix them with a package name
• They are only directly accessible within the physical boundaries of the code block or file scope in which they’re declared. In the code above, $time is only accessible to code physically located inside the for loop and not to code called during or after that loop.
• They usually cease to exist each time the program leaves the code block in which they were declared. In the code above, the variable $time ceases to exist at the end of each iteration of the for loop (and is recreated at the beginning of the next iteration).

 

Generally speaking, package variables are fine for very short programs, but cause problems in larger code. Because package variables are accessible throughout the program source, changes made at one point in the code can unexpectedly affect the program’s behavior elsewhere.

Lexical variables normally cease to exist at the end of the block or file in which they’re declared, but not always. The rule is that a lexical is destroyed at the end of its block unless some other part of the program still has a reference to it. In that case it continues to exist until that reference disappears.

For reference counting, because each lexical has a count associated with it, telling Perl how many references to it exist. Each time another reference to the lexical is cre- ated, the count goes up; each time a reference disappears, the count goes down. Each time the count goes down, Perl checks to see if it hit zero, in which case the variable is destroyed.

The local function takes package variables—but not lexicals—and temporarily replaces their value. Thereafter, any reference to that package variable anywhere in the program accesses that new temporary value. The original value (that is, the value before the call to local) is only restored when execution reaches the end of the block in which the replacement was originally made.

It’s important to be clear about the difference between my and local. The my qualifier creates a new lexical variable, accessible by name only in the current block and not directly accessible in any subroutines called by the current block. Using local temporarily replaces an existing package variable, still accessible by name anywhere, including in subroutines called by the current block.

In other words, lexical variables are restricted to the spatial (syntactic) boundaries of the block in which their my is specified, while localized package variables are restricted to the temporal (execution) boundaries of the block in which their local is called.

If you want a variable with a limited scope and no nasty surprises when distant and un- related code messes with its value you want my. If you want to temporarily change the value of a package variable until the end of the current block, you want local. In practice, you almost always want my.

The standard perlmod and perlmodlib documentation explains the concept of perl modules in detail.

For perl to find a module, the Perl compiler opens the first matching file it finds, and eval’s the text inside it. If the eval fails, compilation is terminated with an error message. That can happen if the file is inaccessible, the code it contains is invalid, or the code doesn’t produce a true value when executed.Whenever a module is successfully located and compiled into a Perl program, the subroutine import belonging to that module is called. The default behavior of import is to do nothing, but you can change that behavior by creating your own import subroutine in the module. When it is called, the import subroutine is passed the name of the module being used as its first argument, followed by any argument list that appears at the end of the use state- ment. For example, if a program included the line:

 

use Database::Access::Control ("my.db");

then, after the Database::Access::Control module had been located and compiled, the subroutine Database::Access::Control::import would automatically be called:  

Database::Access::Control::import("Database::Access::Control","my.db");

Very few people ever write their own import subroutine. Instead, they generally use the Exporter module, which is part of the Perl standard distribution. Exporter makes it easy to take care of the typical tasks for which import is used, namely, importing package variables and subroutines from the module’s name space to the caller’s.

Though important in regular Perl, the Exporter module and the import subroutine are hardly ever used in object-oriented Perl, since exporting variables or subroutines from classes goes against the encapsulation principle of object orientation.  About "AUTOLOAD", Conway's book gives us a very clear explanataion.  For example, if the subroutine Robot::move_arm is invoked:  Robot::move_arm(left=>100); 

but the Robot package doesn't have a subroutine named move_arm, then, before it issues a fatal error, Perl also tries to call Robot::AUTOLOAD.

A package's AUTOLOAD subroutine is always invoked with the argument list that was intended for the missing subroutine. In the above example, Robot::AUTOLOAD would be invoked with the argument list: ("left", 100).

Just gives an example:

package Robot;
sub AUTOLOAD
{
    print"Sorry $AUTOLOAD isn't defined.\n", "(I'll just pretend, shall I?)\n";
}
package Robot;
wash_floor();# Sorry, Robot::wash_floor isn't defined..."
empty_trash("all");# Sorry, Robot::empty_trash isn't defined..."

Of course, polite error messages aren't particularly useful, except during software development. A more interesting application of autoloading is to have the AUTOLOAD subroutine work out what to do, and then actually do it.  In Perl, a closure is just a subroutine that refers to one or more lexical variables declared outside the subroutine itself. For example:

my $name = "Damian";
sub print_my_name    { print $name, "\n"; }

For a piece of code like this, 

{  my $name = "Damian";	sub print_my_name { print $name, "\n" }}

Then the definition of that subroutine confers eternal life on the otherwise-doomed variable $name. In other words, as long as the print_my_name subroutine continues to exist (i.e., for the rest of the program), Perl will make sure that the lexical variable stays available for the sub- routine’s use.

The tricky bit is that, apart from this special relationship with print_my_name, the normal rules of accessibility still apply to the lexical variable. That is, at the end of the block, $name will become inaccessible to the rest of the program, except for print_my_name. Therefore, after the block ends, the only way to access $name is by calling that subroutine.That’s all there is to a closure: a subroutine that preserves any lexical variables it’s using, even after they become invisible everywhere else.

Closures are a means of giving a subroutine its own private memory— variables that per- sist between calls to that subroutine and are accessible only to it. Even more interestingly, two or more closures can share the same private memory or state.

This ability of closures to provide restricted access to certain variables is an excellent, if not unusual, example of the object-oriented concept of encapsulation.

You can access an entire symbol table entry through a special piece of syntax called a typeglob: *symbol_name. To refer to the complete symbol table entry for anything that’s called “FILE”, such as $FILE, %FILE, &FILE, etc., we would use the typeglob *FILE. The slots in that symbol table entry would contain individual references to the package scalar variable $FILE, the package array variable @FILE, the package subroutine &FILE, and so forth.
It’s perfectly possible to take a reference to a typeglob:

$var = 'this is $var';%var = (v=>"very", a=>"active", r=>"rodent");
sub var { print "this is &var\n" }$typeglob_ref = \*var;

There’s yet another way to access variables and subroutines via the symbol table: via a symbolic reference. A symbolic reference is simply a character string containing the name of a variable or subroutine in a particular package’s symbol table.

The subtleties of symbolic references can be a genuine headache when invoked accidentally, so the use strict directive (or, more specifically, use strict "refs") makes them illegal. This is a handy safety feature and no real imposition, since you can always add a no strict "refs" directive to any block where you’re deliberately using a symbolic reference. Symbolic references are not widely used in regular Perl and are even rarer in object-oriented Perl.