⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch02.htm

📁 Web_Programming_with_Perl5,一个不错的Perl语言教程。
💻 HTM
📖 第 1 页 / 共 5 页
字号:
}







$closure = &newanon(`anonymous');











{ # new lexical scope







&$closure(`subroutine');







}



# prints: Hey, I'm in an anonymous subroutine.



</FONT></PRE>



<P>A lexical variable declared within a closure remains intact in future invocations



of the subroutine, even if invoked outside the lexical scope of the declaration.



See PERLSUB and PERLREF for detailed examples and descriptions of closures. <B><TT>Multiple



Simultaneous DBM Implementations</TT></B> The Perl programmer can now access a number



of DBM implementations simultaneously within a program. Perl is now shipped with



SDBM, and consideration is being given to including the Berkeley DB implementation



by default with Perl, but this has not been implemented yet. GDBM, NDBM, and ODBM



are also available, if you have them on your machine. Having simultaneous DBM implementations



makes it easy to convert from one DBM format to another within the same program.</P>



<P>You should note that the older dbmopen() function has been deprecated in favor



of the tie() function. See PERLFUNC for more details on implementing a tie()'d DBM



hash. <B><TT>Flags on </TT>#!<TT> Line</TT></B> Any regular Perl command-line options



(flags) appended after the</P>



<PRE><FONT COLOR="#0066FF">#!/usr/bin/perl



</FONT></PRE>



<P>line in a program are now correctly interpreted, even if the script isn't executed



directly. The startup line:</P>



<PRE><FONT COLOR="#0066FF">#!/usr/bin/perl -d



</FONT></PRE>



<P>will, for instance, invoke the debugger each time the script is run.



<CENTER>



<H4><A NAME="Heading18"></A><FONT COLOR="#000077">Summary of the New Perl5 Features</FONT></H4>



</CENTER>



<P>Perl5 is easier to learn and use and is clearly more powerful than previous major



versions of Perl. Other new features, modules, and documentation that enhance Perl's



usability are also available but haven't been mentioned here. You should explore



them all as time allows.



<CENTER>



<H3><A NAME="Heading19"></A><FONT COLOR="#000077">Extended Perl5 Tutorial</FONT></H3>



</CENTER>



<P>Now that you've been introduced to the new features in Perl5, you're ready to



embark on an extended tutorial on references and modules. You need to understand



how these elements work so that you can make use of the examples to follow in this



book. There's a lot to cover here, so grab a cup of coffee, and I'll try to avoid



monotony. You might find it helpful to be sitting at your computer with your copy



of Perl5 ready to run so that you can try out the sample code as you go along.



<CENTER>



<H4><A NAME="Heading20"></A><FONT COLOR="#000077">References</FONT></H4>



</CENTER>



<P>In the past, the Perl programmer had to go through some contortions to implement



various complex data types, such as arrays of arrays. The notion of a variable that



&quot;pointed&quot; to another data type did not exist. With the advent of Perl5,



you now have the reference variable type. References are actually just standard Perl



scalar variables, which are assigned or initialized to allow them to be used to refer



or &quot;point&quot; to some other Perl data type. References give you powerful new



capabilities when writing Perl programs.</P>



<P>To create a new real reference variable, you use the following general syntax:</P>



<PRE><FONT COLOR="#0066FF">$variable = \datatype;



</FONT></PRE>



<P>Here, you set $variable to be a reference to datatype by preceding datatype with



a backslash. $variable can now be used to refer or assign to datatype using an explicit



form of a dereference, depending on what datatype is. Table 2.2 illustrates the syntax



for using real references. A number of other types of references also exist, each



with its own assignment syntax, but I won't explain those types just yet. <TT>Table



2.2. References: Data types and assignment/dereference syntax.<BR>



<BR>



</TT>



<TABLE BORDER="0">



	<TR ALIGN="LEFT" rowspan="1">



		<TD WIDTH="111" ALIGN="LEFT">Data Type</TD>



		<TD WIDTH="121" ALIGN="LEFT">Assignment Syntax</TD>



		<TD ALIGN="LEFT">Dereference Syntax</TD>



	</TR>



	<TR ALIGN="LEFT" rowspan="1">



		<TD WIDTH="111" ALIGN="LEFT">Scalar</TD>



		<TD WIDTH="121" ALIGN="LEFT">$ref = \$var;</TD>



		<TD ALIGN="LEFT">$$ref</TD>



	</TR>



	<TR ALIGN="LEFT" rowspan="1">



		<TD WIDTH="111" ALIGN="LEFT">Scalar Array</TD>



		<TD WIDTH="121" ALIGN="LEFT">$ref = \@array</TD>



		<TD ALIGN="LEFT">@{$ref} or ${$ref}[0] for individual elements</TD>



	</TR>



	<TR ALIGN="LEFT" rowspan="1">



		<TD WIDTH="111" ALIGN="LEFT">Hash</TD>



		<TD WIDTH="121" ALIGN="LEFT">$ref = \%array</TD>



		<TD ALIGN="LEFT">%{$ref} or ${$ref}{key} for</TD>



	</TR>



	<TR ALIGN="LEFT" rowspan="1">



		<TD WIDTH="111" ALIGN="LEFT">individual elements</TD>



		<TD WIDTH="121" ALIGN="LEFT"></TD>



		<TD ALIGN="LEFT"></TD>



	</TR>



	<TR ALIGN="LEFT" rowspan="1">



		<TD WIDTH="111" ALIGN="LEFT">Reference</TD>



		<TD WIDTH="121" ALIGN="LEFT">$refref = \$ref</TD>



		<TD ALIGN="LEFT">$$$ref</TD>



	</TR>



	<TR ALIGN="LEFT" rowspan="1">



		<TD WIDTH="111" ALIGN="LEFT">Subroutine (CODE)</TD>



		<TD WIDTH="121" ALIGN="LEFT">$ref = \&amp;sub</TD>



		<TD ALIGN="LEFT">&amp;$sub</TD>



	</TR>



	<TR ALIGN="LEFT" rowspan="1">



		<TD WIDTH="111" ALIGN="LEFT">Package</TD>



		<TD WIDTH="121" ALIGN="LEFT">bless $ref, Package</TD>



		<TD ALIGN="LEFT">$ref-&gt;method() $ref-&gt;variable</TD>



	</TR>



</TABLE>



<BR>



<BR>



In the following sections, you'll look at each of these data types in depth, and



I'll demonstrate their use with some examples. These examples should provide you



with some general insight as to how each type of reference can be used, but note



that they are not comprehensive. You can study the full power and capabilities of



references by reading PERLREF and PERLDSC. Another potentially useful document for



studying how references work is the test script for references in the Perl distribution,



called ref.t. Under UNIX, you can find it in the t/op directory under the Perl build



directory. Under Macintosh, the t/op directory should be located within the installation



directory. Under Windows 95, this directory is named ntt, and the file has been given



the .ntt extension. Look for ntt/op/ref.ntt instead of t/op/ref.t under Windows(ntperl).



It contains a complete test suite for all types of Perl references. <B><TT>References



to Scalars</TT></B> Scalar variables, the simplest type of Perl variable, can be



referenced, as can all other types. Although the usefulness of references to simple



scalars may not be immediately evident, referencing is certainly an option.</P>



<P>Consider the following example:</P>



<PRE><FONT COLOR="#0066FF">$foo = &quot;Initial value&quot;;



&amp;update_scalar();



print $foo,&quot;\n&quot;;







sub update_scalar{



    $foo = &quot;Updated&quot;;



}







# prints: Updated



</FONT></PRE>



<P>This example takes a global variable, $foo, and sets it to an initial value; then



it calls the update_scalar subroutine to set it to a new value. Simple enough, but



if the update_scalar subroutine lives in a package, you're out of luck. Observe the



following:</P>



<PRE><FONT COLOR="#0066FF">$foo = &quot;Initial value&quot;;



&amp;test::update_scalar();



print $foo,&quot;\n&quot;;







package test;



sub update_scalar{



$foo = &quot;Updated&quot;;



}







# prints: Initial value



</FONT></PRE>



<P>Here, the $foo variable doesn't get changed because the test package has its own



namespace and its own $foo variable, and can't access the $foo in main without some



specific semantics. When you work with modules and packages, you'll be faced with



this restriction.</P>



<P>So, what to do? Well, you could pass in the $foo from main as a parameter to the



subroutine and try to update it within the subroutine like this:</P>



<PRE><FONT COLOR="#0066FF">$foo = &quot;Initial value&quot;;



&amp;test::update_scalar($foo);



print $foo,&quot;\n&quot;;







package test;







sub update_scalar{



($foo) = @_;



$foo = &quot;Updated&quot;;



}







# prints: Initial value



</FONT></PRE>



<P>Alas, the $foo that gets updated in the update_scalar subroutine is just a copy



of the $foo that is passed in. You're still dealing with two specific variables,



in different packages, and you're essentially passing by value when you make a reassignment



within the subroutine. The experienced Perl4 programmer will recognize that there's



also the option of modifying $_[0] directly, but references provide a cleaner solution.</P>



<P>The solution I've chosen, using a reference to a scalar, is to create a reference



to main's $foo, pass it into the update_scalar subroutine, and then dereference for



the assignment, as follows:</P>



<PRE><FONT COLOR="#0066FF">$foo = &quot;Initial value&quot;;



&amp;test::update_scalar(\$foo);



print $foo,&quot;\n&quot;;







package test;







sub update_scalar{



($foo) = @_;



$$foo = &quot;Updated&quot;;



}







# prints: Updated



</FONT></PRE>



<P>Notice how you implicitly pass the reference to the subroutine by using the backslash



operator on main's $foo variable in the subroutine call. You thus pass main's $foo



by reference to the update_scalar subroutine, and when you assign it to the $foo



in the subroutine, you are actually creating a real reference to the $foo in main.



Using the dereferencing syntax described in Table 2.2, you then can change $main::foo



implicitly through the reference, using the $$foo dereferencing syntax.</P>



<P>References to scalar types have many uses; this simple example describes only



one. You'll see others as you continue to read through the chapters of this book.



<B><TT>References to Scalar Arrays</TT></B> Scalar arrays are arrays of Perl scalar



types. You declare them using the @name syntax. Using a reference to the scalar array



enables you to access the elements of an array individually or refer to the entire



array, as shown in Table 2.2. Of course, you also can use the reference anywhere



an array is expected, such as within a foreach() loop. The following example again



illustrates the usefulness of references when passing arguments to subroutines. Consider



the following code:</P>



<PRE><FONT COLOR="#0066FF">@array1 = (1, 3, 5);



@array2 = (2, 4, 6);



</FONT></PRE>



<P>Now, what if you want to pass these arrays to a Perl subroutine and then access



them within the subroutine, possibly modifying their values? If you've ever tried



to pass two or more arrays to a Perl subroutine, then you know that it can't be done



easily, because there's no way to determine where the first array ends and the next



one begins. (Recall that the parameters passed to a Perl subroutine are accessible



only through the @_ array and thus appear to be a single array to the subroutine



that receives them.)</P>



<P>Using references, you can circumvent this limitation. If you create references



to each of the preceding arrays, you can easily pass two scalars to the subroutine



and then dereference the arrays those scalars have been assigned to, like this:</P>



<PRE><FONT COLOR="#0066FF">@array1 = (1, 3, 5);



@array2 = (2, 4, 6);



$ref1 = \@array1;



$ref2 = \@array2;



@sum = &amp;array_adder($ref1, $ref2);



print &quot;\@sum = (&quot;, join(`,',@sum), &quot;)\n&quot;;







sub array_adder{



my($ref1, $ref2) = @_;



my $i = 0;



my @sum;



for($i = 0; $i &lt;= $#{$ref1} ; $i++){



    $sum[$i] = ${$ref1}[$i] + ${$ref2}[$i];



}



return @sum;



}







# prints: @sum = (3,7,11)



</FONT></PRE>



<P>Here, you've created a new array, whose elements are the sum of the individual



elements of two equal-length arrays' elements. That's easy, but you do it by passing



the arrays to a subroutine using references and thus make a formerly difficult, or



at least nonintuitive, task easier. In Perl4, you would have had to either use glob



types or have passed in the length of the arrays as the first or last argument and



then split @_ appropriately. Not pretty.</P>



<P>Note how you are able to use the reference within the subroutine in the $#array



context (the highest index of the array from zero-base), as well as access the individual



elements of the arrays that are being referred to. Again, this is just one single



use for references to arrays. See the documentation mentioned previously for many



more examples, PERLLOL for instance. <B><TT>References to Hashes (Associative Arrays)</TT></B>



When you create a reference to an associative array (hash), you can access all the



keys and values of the associative array through the reference. You can also use



the reference in place of the hash, using the syntax in Table 2.2, within any given



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -