📄 ch6.htm
字号:
<HTML>
<HEAD>
<TITLE>Chapter 6 -- Binding Variables to Objects</TITLE>
<META NAME="GENERATOR" CONTENT="Mozilla/3.0b5aGold (WinNT; I) [Netscape]">
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000EE" VLINK="#551A8B" ALINK="#CE2910">
<H1><FONT COLOR=#FF0000>Chapter 6</FONT></H1>
<H1><B><FONT SIZE=5 COLOR=#FF0000>Binding Variables to Objects</FONT></B>
</H1>
<P>
<HR WIDTH="100%"></P>
<P>
<H3 ALIGN=CENTER><FONT COLOR="#000000"><FONT SIZE=+2>CONTENTS<A NAME="CONTENTS"></A>
</FONT></FONT></H3>
<UL>
<LI><A HREF="#ThetieFunction" >The tie() Function</A>
<LI><A HREF="#TyingScalars" >Tying Scalars</A>
<LI><A HREF="#TyingtoanArray" >Tying to an Array</A>
<LI><A HREF="#TyingtoanAssociativeArray" >Tying to an Associative Array</A>
<LI><A HREF="#ForMoreInformation" >For More Information</A>
<LI><A HREF="#Summary" >Summary</A>
</UL>
<HR>
<P>
This chapter is dedicated to describing how the <TT><FONT FACE="Courier">tie()</FONT></TT>
function works in Perl. The <TT><FONT FACE="Courier">tie()</FONT></TT>
function enables you to create variables that are tied to specific
methods called when a variable is written to or read from. Using
the <TT><FONT FACE="Courier">tie()</FONT></TT> function, you can
eliminate the need for calling methods designed specifically for
certain types of variables.
<H2><A NAME="ThetieFunction"><FONT SIZE=5 COLOR=#FF0000>The </FONT><TT><FONT SIZE=5 COLOR=#FF0000 FACE="Courier">tie()</FONT></TT><FONT SIZE=5 COLOR=#FF0000>
Function</FONT></A></H2>
<P>
The <TT><FONT FACE="Courier">tie()</FONT></TT> function is used
to bind a variable to an object class. Here's the syntax:
<BLOCKQUOTE>
<TT><FONT FACE="Courier">tie ($<I>variable,</I>$<I>classname,</I>@<I>list</I>);</FONT></TT>
</BLOCKQUOTE>
<P>
The <TT><FONT FACE="Courier">tie()</FONT></TT> function binds
a variable to a class that then provides the methods for the variable.
The <TT><FONT FACE="Courier">$<I>variable</I></FONT></TT> has
to be set to the name of the variable to be tied. The <TT><FONT FACE="Courier">$<I>classname</I></FONT></TT>
is the name of the class implementing objects to which you want
the variable tied. The <TT><FONT FACE="Courier">@<I>list</I></FONT></TT>
is the list of arguments that may be required for this variable's
class methods.
<P>
The object returned by the <TT><FONT FACE="Courier">tie()</FONT></TT>
function is just like the <TT><FONT FACE="Courier">new()</FONT></TT>
function for an object. You can use the returned value from the
<TT><FONT FACE="Courier">tie()</FONT></TT> function to access
other methods in the class you just tied the object to.
<P>
Once you tie a variable to a class, the class's behavior is reflected
in the way you access the variable. Each of the methods for the
type of object is called when the type of action for the variable
is seen by Perl. Three types of objects can be tied to classes:
scalars, arrays, and associative arrays.
<P>
It's often necessary to disassociate an object from a class. This
is done with the use of the <TT><FONT FACE="Courier">untie()</FONT></TT>
function. Simply call the <TT><FONT FACE="Courier">untie($<I>object</I>)</FONT></TT>
function and you're done. The <TT><FONT FACE="Courier">untie()</FONT></TT>
function works whether you are tied to a scalar, array, or hash
object. The next three sections illustrate how to use <TT><FONT FACE="Courier">tie()</FONT></TT>
on each of these objects.
<H2><A NAME="TyingScalars"><FONT SIZE=5 COLOR=#FF0000>Tying Scalars</FONT></A>
</H2>
<P>
A class implementing a scalar object that can be tied to must
implement these four methods:
<UL>
<LI><TT><FONT FACE="Courier">TIESCALAR classname, LIST</FONT></TT>
<LI><TT><FONT FACE="Courier">FETch this</FONT></TT>
<LI><TT><FONT FACE="Courier">STORE this, value</FONT></TT>
<LI><TT><FONT FACE="Courier">DESTROY this</FONT></TT>
</UL>
<P>
Think of these methods as events for the class. When a variable
is first tied to a class, the <TT><FONT FACE="Courier">TIESCALAR</FONT></TT>
method is called. Every time the tied variable is read from, the
value from the <TT><FONT FACE="Courier">FETch</FONT></TT> method
is returned. When the tied variable is assigned to, the <TT><FONT FACE="Courier">STORE</FONT></TT>
method is called. Finally, when the tied variable loses scope,
the <TT><FONT FACE="Courier">DESTROY</FONT></TT> method is called.
<P>
Listing 6.1 contains a script that uses the <TT><FONT FACE="Courier">tie()</FONT></TT>
function for the <TT><FONT FACE="Courier">Knot</FONT></TT> class.
<HR>
<BLOCKQUOTE>
<B>Listing 6.1. Using the </B><TT><B><FONT FACE="Courier">tie()</FONT></B></TT><B>
function.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier"> 1 #!/usr/bin/perl<BR>
2<BR>
3 push(@Inc,".");
<BR>
4 use Knot;<BR>
5<BR>
6 #<BR>
7 # From now on the
variable $currentTime<BR>
8 # will behave as defined in functions in Knot.pm<BR>
9 #<BR>
10 tie $currentTime, 'Knot';<BR>
11<BR>
12 #<BR>
13 # Test the FETch method<BR>
14 #<BR>
15 $x = $currentTime;<BR>
16 print " x= $x\n";<BR>
17 print " current = $currentTime\n";<BR>
18<BR>
19 #<BR>
20 # Test the STORE method<BR>
21 #<BR>
22 # In Knot.pm we have defined the $currentTime<BR>
23 # variable to behave as a readonly object.<BR>
24 # The following message will bail out with an error message.
<BR>
25 #<BR>
26 $currentTime = $x;<BR>
27<BR>
28<BR>
29 #<BR>
30 # As soon as we drop out of the script here, the DESTROY<BR>
31 # method will be called on $currentTime.<BR>
32 #</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
Let's examine the code in Listing 6.1 to see where the methods
for <TT><FONT FACE="Courier">Knot.pm</FONT></TT> are invoked.
In line 3, the address of the current directory is added to search
for included modules. In line 4, the <TT><FONT FACE="Courier">Knot.pm</FONT></TT>
module is requested with the <TT><FONT FACE="Courier">use</FONT></TT>
statement. The <TT><FONT FACE="Courier">Knot.pm</FONT></TT> file
contains the module code for the class that allows variables to
be tied.
<P>
In line 10, the variable <TT><FONT FACE="Courier">$currentTime</FONT></TT>
is tied to the class <TT><FONT FACE="Courier">Knot</FONT></TT>.
The <TT><FONT FACE="Courier">TIESCALAR</FONT></TT> function in
<TT><FONT FACE="Courier">Knot.pm</FONT></TT> is called at this
point. There are no additional arguments to be passed to the <TT><FONT FACE="Courier">TIESCALAR</FONT></TT>
function, so only two parameters, the variable number and the
class name, are sent.
<P>
In line 15, the <TT><FONT FACE="Courier">$currentTime</FONT></TT>
variable is read from and the value of <TT><FONT FACE="Courier">$currentTime</FONT></TT>
is assigned to <TT><FONT FACE="Courier">$x</FONT></TT>. Instead
of treating <TT><FONT FACE="Courier">$currentTime</FONT></TT>
as a normal variable, Perl uses the <TT><FONT FACE="Courier">FETch</FONT></TT>
method of the tied class. The <TT><FONT FACE="Courier">FETch</FONT></TT>
method returns the current date in this example. You can write
your own function. In line 17, the <TT><FONT FACE="Courier">$currentTime</FONT></TT>
variable is accessed again. This time, the <TT><FONT FACE="Courier">FETch</FONT></TT>
method is called again.
<P>
The program must not attempt to assign a value to the <TT><FONT FACE="Courier">$currentTime</FONT></TT>
variable. See line 26 in Listing 6.1. The <TT><FONT FACE="Courier">Knot.pm</FONT></TT>
module is implemented to allow only read-only variables; therefore,
the <TT><FONT FACE="Courier">FETch</FONT></TT> function will print
an error message when the code at line 26 is executed.
<P>
Finally, the <TT><FONT FACE="Courier">DESTROY</FONT></TT> method
is called when the <TT><FONT FACE="Courier">$currentTime</FONT></TT>
variable is destroyed. The destruction is done automatically by
Perl when the <TT><FONT FACE="Courier">$currentTime</FONT></TT>
variable goes out of scope. In this example, the <TT><FONT FACE="Courier">DESTROY</FONT></TT>
method simply prints an error message.
<P>
Here is the output from Listing 6.1.
<BLOCKQUOTE>
<TT><FONT FACE="Courier"> x= Sat Jun 1 12:54:25
CDT 1996<BR>
<BR>
current = Sat Jun 1
12:54:25 CDT 1996<BR>
<BR>
Hey dude! We are making this readonly!<BR>
at Knot.pm line 54<BR>
</FONT></TT> <TT><FONT FACE="Courier">Knot::STORE
called at ./6_1.pl line 26<BR>
<BR>
Knot:: unknotted!</FONT></TT>
</BLOCKQUOTE>
<P>
Now let's look at the <TT><FONT FACE="Courier">Knot.pm</FONT></TT>
file in Listing 6.2.
<HR>
<BLOCKQUOTE>
<B>Listing 6.2. The </B><TT><B><FONT FACE="Courier">Knot.pm</FONT></B></TT><B>
file.<BR>
</B>
</BLOCKQUOTE>
<BLOCKQUOTE>
<TT><FONT FACE="Courier"> 1 #!/usr/bin/perl<BR>
2<BR>
3 # ----------------------------------------------------------------
<BR>
4 # Sample file that shows how to tie variables to classes.
<BR>
5 #<BR>
6 # This library is hereby placed in the public domain.
Copy freely<BR>
7 # as long as you
give me credit for it!<BR>
8 # Kamran Husain. khusain@ikra.com<BR>
9 # ----------------------------------------------------------------
<BR>
10 package Knot;<BR>
11 use Carp;<BR>
12 use strict;<BR>
13<BR>
14 #<BR>
15 # TIESCALAR classname, argument-list-here<BR>
16 # This is the constructor for the class. It
returns a reference<BR>
17 # to a new object for the class name.
<BR>
18 #<BR>
19 sub TIESCALAR {<BR>
20 my $class
= shift;<BR>
21 my $this
= {};<BR>
22 #<BR>
23 # print "\n $class, $this";
<BR>
24 #<BR>
25 return
bless \$this, $class;<BR>
26 }<BR>
27<BR>
28 #<BR>
29 # FETch this<BR>
30 # The FETch method will be triggered every time the tied variable
<BR>
31 # is accessed.<BR>
32 # The only argument to this function is the object itself.
<BR>
33 # In this case, we just return the date.<BR>
34 #<BR>
35 sub FETch {<BR>
36
my $self = shift;<BR>
37
confess "wrong type" unless ref $self;<BR>
38
croak "usage error" if @_;<BR>
39
my $override;<BR>
40
$override = 'date';<BR>
41
return $override;<BR>
42
}<BR>
43<BR>
44 #<BR>
45 # STORE this, value<BR>
46 # This method will be triggered every time the tied variable
is<BR>
47 # written to. It expects only two arguments: a reference to
itself<BR>
48 # and a value that is being assigned.<BR>
49 #<BR>
50 sub STORE {<BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -