📄 ch6.htm
字号:
<BR>
52<BR>
53<BR>
54 # STORE this, key, value<BR>
55 #
This method is called whenever an element in the hash is<BR>
56 # written to. It takes
three arguments: a reference to itself, the<BR>
57 #
index to store at, and the value to store.<BR>
58<BR>
59 sub STORE {<BR>
60 my
$self = shift; # this<BR>
61 my
$fname = shift; # the key<BR>
62 my
$value = shift; # the value<BR>
63 my
$dir = $self->{HOME};<BR>
64 my
$file = "$dir/$fname";<BR>
65 print
"Storing $fname, $value $file \n";<BR>
66 if
($value eq "done") {<BR>
67
print "Storing $fname, $value $file \n";<BR>
68 return
$self->{LIST}->{$fname} = 'head -1 $file';<BR>
69
}<BR>
70 else {
<BR>
71 return
$self->{LIST}->{$fname} = $value;<BR>
72
}<BR>
73 }
<BR>
74<BR>
75 # DELETE this, key
<BR>
76 #<BR>
77 # This
method is called when an item is deleted from the hash.<BR>
78 #<BR>
79 sub DELETE {
<BR>
80<BR>
81 my
$self = shift;<BR>
82 my
$fname = shift;<BR>
83 my
$dir = $self->{HOME};<BR>
84 my
$file = "$dir/$fname";<BR>
85 delete
$self->{LIST}->{$fname};<BR>
86 }
<BR>
87<BR>
88 # CLEAR this<BR>
89 #
This method is called when the whole hash is set to an empty list.
<BR>
90 #<BR>
91 sub CLEAR {
<BR>
92 my
$self = shift;<BR>
93 my
$fname;<BR>
94 foreach
$fname ( keys %{$self->{LIST}}) {<BR>
95 $self->DELETE($fname);
<BR>
96 }
<BR>
97 }
<BR>
98<BR>
99 #<BR>
100 # EXISTS this, key<BR>
101 # This method is called when the exists()
is called on a hash.<BR>
102 #<BR>
103 sub EXISTS {<BR>
104 my
$self = shift;<BR>
105 my
$dir = $self->{HOME};<BR>
106 my
$fname = shift;<BR>
107 my
$file = "$dir/$fname";<BR>
108 return
exists $self->{LIST}->{$file};<BR>
109 }
<BR>
110<BR>
111 # FIRSTKEY this<BR>
112 # This method is called when you start
to iterate a list.<BR>
113 #<BR>
114 sub FIRSTKEY {<BR>
115 my
$self = shift;<BR>
116 my
$x = keys %{$self->{LIST}};<BR>
117 each
%{$self->{LIST}}<BR>
118 }
<BR>
119<BR>
120<BR>
121 #<BR>
122 # NEXTKEY this, lastkey<BR>
123 # This method is called
during a keys() or each() iteration. The<BR>
124 # first argument is the object itself. The second argument
is the last<BR>
125 # key that was accessed.<BR>
126<BR>
127 sub NEXTKEY {<BR>
128 my
$self = shift;<BR>
129 return
each %{ $self->{LIST} }<BR>
130 }
<BR>
131<BR>
132<BR>
133 #<BR>
134 # DESTROY the infamous epitaph!<BR>
135 #<BR>
136 sub DESTROY { print "\n All done!"; }
<BR>
137<BR>
138 1;</FONT></TT>
</BLOCKQUOTE>
<HR>
<P>
The <TT><FONT FACE="Courier">TIEHASH</FONT></TT> function definition
begins at line 10. The constructor takes two values as arguments:
the first is the name of the class, and the second is an optional
directory to work in. If the second parameter is not specified,
the current working directory is used. The <TT><FONT FACE="Courier">$node</FONT></TT>
hash is used to store two parameters: <TT><FONT FACE="Courier">HOME</FONT></TT>
for the working directory and <TT><FONT FACE="Courier">LIST</FONT></TT>
for the list of items in this hash.
<P>
At line 21, the required information is collected for the hash
and is stored away in <TT><FONT FACE="Courier">LIST</FONT></TT>
at line 23. The <TT><FONT FACE="Courier">debug</FONT></TT> statement
at line 24 is a very valuable tool while debugging. At line 27,
the class is blessed and the reference to the <TT><FONT FACE="Courier">$node</FONT></TT>
is returned.
<P>
The <TT><FONT FACE="Courier">FETch</FONT></TT> method is called
whenever an element in the tied hash is being read. It takes two
arguments: a reference to itself and the key whose value is being
asked for. See lines 37 and 38, where the two parameters are extracted.
It would be prudent to add some error correction here lest we
look at the wrong path-this is done at line 41. At line 45 the
returned value as cached in the <TT><FONT FACE="Courier">init</FONT></TT>
stages is returned. Had a new item to the hash been added with
an undefined value, the code at line 45 would assign it a value.
<P>
The assignment-handling function is the <TT><FONT FACE="Courier">STORE</FONT></TT>
function. This function is called whenever an element in the hash
is written to. It takes three arguments: a reference to itself,
the index at which to store, and the value to store. The three
arguments are extracted at lines 60 through 62. The third argument
may be null, in which case the head of the file in the <TT><FONT FACE="Courier">HOME</FONT></TT>
directory is used. (Look at lines 66 through 72.)
<P>
The <TT><FONT FACE="Courier">DELETE</FONT></TT> function is called
when an item is deleted from the hash. The function is defined
at line 81. There are two arguments to this function: a reference
to the object and the index to remove. The <TT><FONT FACE="Courier">delete()</FONT></TT>
function is called to remove the indexed item from the <TT><FONT FACE="Courier">LIST</FONT></TT>
hash at <BR>
line 85.
<P>
The <TT><FONT FACE="Courier">CLEAR</FONT></TT> function is called
when the whole hash is removed, possibly by assigning an empty
list to it. (The tied array has no such callback!) There is only
one argument to this function, and that is a reference to itself.
The <TT><FONT FACE="Courier">CLEAR</FONT></TT> function is set
to call the <TT><FONT FACE="Courier">DELETE</FONT></TT> function
in this example (see line 95). This call saves some code, but
we could have just as easily used the <TT><FONT FACE="Courier">delete()</FONT></TT>
function in the same manner as <TT><FONT FACE="Courier">DELETE</FONT></TT>.
<P>
The <TT><FONT FACE="Courier">EXISTS</FONT></TT> function is called
to check whether an item exists in a hash (see line 103). There
are two arguments to this function: a reference to the object
and the index to remove. It simply re-creates the key and uses
this key to return a value from within the <TT><FONT FACE="Courier">LIST</FONT></TT>
hash.
<P>
The <TT><FONT FACE="Courier">FIRSTKEY</FONT></TT> and <TT><FONT FACE="Courier">NEXTKEY</FONT></TT>
methods are called when the <TT><FONT FACE="Courier">each()</FONT></TT>
and <TT><FONT FACE="Courier">keys()</FONT></TT> methods are called.
The <TT><FONT FACE="Courier">FIRSTKEY</FONT></TT> method is called
when you start to iterate a list. The <TT><FONT FACE="Courier">NEXTKEY</FONT></TT>
method gets called during a <TT><FONT FACE="Courier">keys()</FONT></TT>
or <TT><FONT FACE="Courier">each()</FONT></TT> iteration. The
first argument to <TT><FONT FACE="Courier">NEXTKEY</FONT></TT>
is a reference to the object itself. The second argument is the
last that was accessed.
<P>
For the file in Listing 6.6, you should now be able to derive
your own classes for mapping hashes to functions. The <TT><FONT FACE="Courier">tie()</FONT></TT>
function, when used with hashes, provides more flexibility in
defining methods than what the <TT><FONT FACE="Courier">tie()</FONT></TT>
function for arrays provides. However, using the hash is more
complex than the array function because you have to define more
methods with the hashing method.
<P>
There is supposedly some relief, though, with the use of the <TT><FONT FACE="Courier">TieHash</FONT></TT>
module provided with the Perl distribution. The <TT><FONT FACE="Courier">TieHash</FONT></TT>
module has predefined methods for you to pick and choose whatever
functions you want to implement, and the rest are defaulted. There
is a <TT><FONT FACE="Courier">man</FONT></TT> page for the module
in the Perl distribution, but it did not provide much information
on how to actually use the module. Perhaps we'll see more documentation
on this tool in later releases.
<H2><A NAME="ForMoreInformation"><FONT SIZE=5 COLOR=#FF0000>For
More Information</FONT></A></H2>
<P>
This chapter has provided only some basic information on the use
of the <TT><FONT FACE="Courier">tie()</FONT></TT> function. There
is an excellent document, called <TT><FONT FACE="Courier">perltie.html</FONT></TT>,
by Tom Christiansen that is available at most of the Perl archive
sites. The <TT><FONT FACE="Courier">perltie.html</FONT></TT> document
has more detailed information on how to use the <TT><FONT FACE="Courier">tie()</FONT></TT>
functions. The <TT><FONT FACE="Courier">tie()</FONT></TT> function
is also used in modules distributed with Perl. Two interesting
modules to look at are the <TT><FONT FACE="Courier">Config</FONT></TT>
and <TT><FONT FACE="Courier">DBM</FONT></TT> file modules, which
show interesting uses of the <TT><FONT FACE="Courier">tie()</FONT></TT>
function. The <TT><FONT FACE="Courier">DBM</FONT></TT> file modules
provide detailed examples of mapping records to disk with the
use of <TT><FONT FACE="Courier">tie()</FONT></TT> functions on
hashes.
<H2><A NAME="Summary"><FONT SIZE=5 COLOR=#FF0000>Summary</FONT></A>
</H2>
<P>
This chapter has provided the basic information on how to use
the <TT><FONT FACE="Courier">tie()</FONT></TT> function to provide
an association between a Perl variable and executable functions.
Scalars, arrays, and hashes can be associated with methods having
special names such as <TT><FONT FACE="Courier">FETch</FONT></TT>,
<TT><FONT FACE="Courier">STORE</FONT></TT>, and so on. By designing
classes that provide methods these names, you can provide extra
functionality to map scalar, array, or hash objects to other objects,
processes, or disk files.
<P>
<HR WIDTH="100%"></P>
<CENTER><P><A HREF="ch5.htm" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/ch5.htm"><IMG SRC="pc.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/pc.gif" BORDER=0 HEIGHT=88 WIDTH=140></A><A HREF="#CONTENTS"><IMG SRC="cc.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/cc.gif" BORDER=0 HEIGHT=88 WIDTH=140></A><A HREF="index.htm" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/index.htm"><IMG SRC="hb.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/hb.gif" BORDER=0 HEIGHT=88 WIDTH=140></A><A HREF="ch7.htm" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/ch7.htm"><IMG
SRC="nc.gif" tppabs="http://www.mcp.com/815097600/0-672/0-672-30891-6/nc.gif" BORDER=0 HEIGHT=88 WIDTH=140></A></P></CENTER>
<P>
<HR WIDTH="100%"></P>
</BODY>
</HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -