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

📄 ch02.htm

📁 Web_Programming_with_Perl5,一个不错的Perl语言教程。
💻 HTM
📖 第 1 页 / 共 5 页
字号:
Perl function that operates on associative arrays or their elements, such as keys(),



foreach(), and delete().</P>



<P>Hash references are extremely powerful. Using them, you can build up complex data



structures containing all the Perl data types or references to those types. In the



following example, you use the standard assignment/dereference syntax described previously



and one of the other dereferencing syntaxes:</P>



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



%Hash = (



    `foo'=&gt; `bar',



    `aref' =&gt; \@array,



    `internalhash' =&gt; {



                       `birds' =&gt; `duck', 



                       `plants' =&gt; `tomato'



                      }



);







# print out the simple scalar element



print $Hash{`foo'}, &quot;\n&quot;;







# print out the elements of @array



print join(` `,@{$Hash{`aref'}}),&quot;\n&quot;;







# print out the elements of the %internalhash



foreach $key  (keys( %{$Hash{`internalhash'}} )){



    print &quot;Key is $key, value is $Hash{`internalhash'}-&gt;{$key} \n&quot;;



}







# prints:



bar



1 2 3



Key is plants, value is tomato



Key is birds, value is duck



</FONT></PRE>



<P>Note how you dereference the value corresponding to the internal hash key of %Hash



by using the -&gt; dereferencing operator. You can use -&gt; because the value is



itself a reference to an anonymous hash. Because it's a reference, you can use it



as a regular scalar element of the array and still emulate a multidimensional hash.







<DL>



	<DT></DT>



</DL>







<CENTER>



<H3>



<HR WIDTH="84%">



<BR>



<FONT COLOR="#000077">CAUTION:</FONT></H3>



</CENTER>











<BLOCKQUOTE>



	<P>Remember, in spite of appearances, arrays are always one dimensional within Perl.



	You're only emulating multidimensionality here by using references. See PERLDSC for



	more details.<BR>



	



<HR>











</BLOCKQUOTE>







<P><B><TT>References to References</TT></B> References, like any other Perl data



type, can have references to themselves. You may, for instance, have several references



to various types or data structures that you want to group together under a single



reference. Here's an example:</P>



<PRE><FONT COLOR="#0066FF">$scalar = &quot;a string&quot;;  # a regular scalar



$array = [1, 2, 3];    # anonymous array



$hash = {&quot;foo&quot; =&gt; &quot;bar&quot;, &quot;baz&quot; =&gt; &quot;blech&quot;}; # anonymous hash



$scalarref = \$scalar;  # ref to scalar



$refref = [\$scalarref, \$array, \$hash];  # anon array of refs to refs







# print out the contents of the ref to ref to scalar



print $${$refref-&gt;[0]},&quot;\n&quot;;







# print out the elements of the ref to ref to array



print join(` `,@{${$refref-&gt;[1]}}),&quot;\n&quot;;







# print out the elements of the ref to ref to hash



foreach $key  (keys( %{${$refref-&gt;[2]}} )){



    print &quot;Key is $key, value is ${${$refref-&gt;[2]}}{$key} \n&quot;;



}







# prints:



a string



1 2 3



Key is foo, value is bar



Key is baz, value is blech



</FONT></PRE>



<P>You can go as deep as you like with references to references. Of course, at some



point, readability may suffer. I recommend readability over complexity in most cases,



especially in a public interface to a module or library, or within code that may



require modifications by someone other than yourself in the future. <B><TT>References



to Subroutines</TT></B> The last type of standard reference to look at, before getting



to blessed references and object-<BR>



oriented Perl, is the reference to code. Specifically, let's look at how to set up



and use a reference to a subroutine.</P>



<P>References to subroutines may be useful in a number of situations. You can use



them to implement closures, as previously described, or as subroutine parameters,



or as part of complex data types. Subroutine references are also useful within packages,



but note that you can't take an external (to a package) reference to a subroutine



which is within the external package, because of inheritance. See PERLSUB for more



details.</P>



<P>The following example illustrates a simple case in which you set up an array of



references to subroutines in the same package. Here, you use two types of references



to access the subroutines:</P>



<PRE><FONT COLOR="#0066FF">sub foo{



    return &quot;I\'m in foo now\n&quot;;



}







sub bar{



    return &quot;Here I am in bar\n&quot;;



}















%subrefs = (`foo' =&gt; \&amp;foo, `bar' =&gt; `bar', ); # bar is a &quot;fake&quot; reference







while(($key,$ref) = each(%subrefs)){



   print ${key}, &quot; : &quot;, &amp;$ref;



}







# prints:



foo : I'm in foo now



baz : Here I am in baz



</FONT></PRE>



<P>You set up a single hash to contain multiple references to subroutines. The potential



for dynamic runtime decision trees should be evident. You could arbitrarily assign



references to subroutines at runtime, based on some input parameters, for instance,



then execute the subroutines using the references. You could have easily done the



same with a regular scalar array, emulating a C-style array of pointers to functions--not



as powerful as a hash of function pointers, but potentially useful.</P>



<P>Note how, in the preceding example when setting up the reference to the bar subroutine



in the %subrefs declaration, I didn't use the \ operator to prepend it. Instead,



you use a fake reference, which is another way to access a given data type by its



name. This technique could also be used in Perl4; however, it works for any data



type in Perl5, and it is an actual reference in Perl5. You can easily declare another



(fake) reference to fake reference, to any depth. The ref.t test suite has a nice



example for using fake references. I won't discuss them much more, because they're



not widely used, but they're worth noting. <B><TT>References to Packages (When Blessed)</TT></B>



When the reference variable refers to a Perl package and has been blessed into the



package, as shown in Table 2.2, it is known as a Perl object. It can then be used



to store, and allow access to, any Perl data type that is used by the package, akin



to public instance variables being accessed by a reference in C++.</P>



<P>You also can use the blessed reference to invoke the methods of the package, also



analogous to a C++ class reference. When you use a blessed reference in this way,



the method that gets invoked automatically has access to the object. This technique



is very common in the Perl modules, and it's very powerful. You need to have a clear



understanding of it in order to use and reuse the examples in this book and modify



them to suit your needs.</P>



<P>Let me give you a simple example to illustrate the concepts. In this example,



the object is a reference to hash. You could simplify it to a reference to array



or scalar, if it were appropriate. A hash reference gives the most flexibility to



access and grow the object dynamically. Consider the following:</P>



<PRE><FONT COLOR="#0066FF">package Customer;







sub new {



my $type = shift;



my %args = @_;



my $self = {};







$self-&gt;{`Name'} =



    length($args{`Name'}) ? $args{`Name'} : &quot;No name given&quot;;



$self-&gt;{`Vitals'} =



    defined(@{$args{`Vitals'}}) ? $args{`Vitals'} : [&quot;No vitals&quot;];



bless $self, $type;



}







sub dumpcust{



my $self = shift;







# Print out the values for the object



print $self-&gt;{Name},&quot;\n&quot;;



print join(` `,@{$self-&gt;{Vitals}}),&quot;\n&quot;;



}







package main;







# Create a new customer object



$cust  = Customer-&gt;new( `Name' =&gt; &quot;Billy T. Kid&quot;,



        `Vitals' =&gt; [&quot;Age : 42&quot;, &quot;Sex : M&quot;] );







# Invoke the method to print out the values for the object



print $cust-&gt;dumpcust;







# prints:



Billy T. Kid



Age : 42 Sex : M



</FONT></PRE>



<P>In this simple example, you see how to initialize the Perl object, which is a



reference to hash, with both scalar elements and a reference to a scalar array. Then



you invoke the dumpcust() method from the Customer package or class, using the blessed



reference.</P>



<P>I'll continue to develop this example as we progress into the extended study of



the Perl module, and the object-oriented features of Perl programming.



<CENTER>



<H4><A NAME="Heading22"></A><FONT COLOR="#000077">An In-Depth Look at Perl5 Modules</FONT></H4>



</CENTER>



<P>You're now ready to take an extended look at Perl5 modules. In the following sections,



I'll give you a short history of the extensibility of Perl to demonstrate the usefulness



of modules. Then we'll look at the general style and process for implementing a module.



<CENTER>



<H4><A NAME="Heading23"></A><FONT COLOR="#000077">The Short History of Perl Extensions</FONT></H4>



</CENTER>



<P>In earlier versions of Perl, a number of external APIs, or extensions, were added



to Perl to give it additional features or functionality. This was accomplished by



compiling the Perl source code with source code that &quot;glued in&quot; the desired



functions from the API. Linking with the external libraries for the desired API then



created a new Perl executable. The following are a few examples:







<UL>



	<LI>cursePerl: UNIX terminal control routines



	<P>



	<LI>tkPerl: Tk routines for screen graphics and widgets



	<P>



	<LI>sybPerl: Sybase database manipulation routines



</UL>







<P>Each of these executables had to be separately maintained by the person at the



site who compiled Perl, and each time one of the APIs was revised, that person had



to rebuild the complete API-specific Perl executable, relinking it with the new library



and working out any problems that might show up with the newer version. Perl5 has



outdated this tedious process. Nowadays, when you want to add features to Perl by



linking with some external library, you use a completely different techniques.



<CENTER>



<H4><A NAME="Heading24"></A><FONT COLOR="#000077">Modules and Extensions: Purpose



and Design</FONT></H4>



</CENTER>



<P>Version 5 of Perl implements the module as the standardized means for extending



its functionality. A Perl module is very much like a Perl library in that it provides



the user with a set of functions or variables, within a separate namespace known



as a Perl package. The purpose of these functions or variables is to simplify and



standardize the implementation of a given task or tasks.</P>



<P>Modules can be much more powerful and useful than the old-style Perl libraries,



however. First, they can now be implemented as a shared library and thus, on many



platforms, eliminate the need for a separate, statically linked Perl executable for



each external API that is desired as a Perl extension. Second, they can be implemented



to provide an interface for use in the new, object-oriented way. <B><TT>Extension



Modules: Modules That Interface to External APIs</TT></B> A Perl5 module provides



the implementor with the means, through the use of XSUBs, to compile C code that



&quot;wraps&quot; or &quot;glues&quot; the functionality of an API into a shared



library that can be loaded by Perl at runtime. After Perl loads the shared library,



through a use or require statement, the glue code enables the end user to call the



API's functions from within the Perl program, passing Perl data types in and out.



This capability is one of the most powerful and useful new features in Perl5.







<DL>



	<DT></DT>



</DL>







<CENTER>



<H3>



<HR WIDTH="83%">



<BR>



<FONT COLOR="#000077">NOTE:</FONT></H3>

⌨️ 快捷键说明

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