📄 perltie.1
字号:
in some special way. See nvi and the Apache module for examples..PPIn our example we're going to create a shouting handle..PP.Vb 1\& package Shout;.Ve.IP "\s-1TIEHANDLE\s0 classname, \s-1LIST\s0" 4.IX Xref "TIEHANDLE".IX Item "TIEHANDLE classname, LIST"This is the constructor for the class. That means it is expected toreturn a blessed reference of some sort. The reference can be used tohold some internal information..Sp.Vb 1\& sub TIEHANDLE { print "<shout>\en"; my $i; bless \e$i, shift }.Ve.IP "\s-1WRITE\s0 this, \s-1LIST\s0" 4.IX Xref "WRITE".IX Item "WRITE this, LIST"This method will be called when the handle is written to via the\&\f(CW\*(C`syswrite\*(C'\fR function..Sp.Vb 5\& sub WRITE {\& $r = shift;\& my($buf,$len,$offset) = @_;\& print "WRITE called, \e$buf=$buf, \e$len=$len, \e$offset=$offset";\& }.Ve.IP "\s-1PRINT\s0 this, \s-1LIST\s0" 4.IX Xref "PRINT".IX Item "PRINT this, LIST"This method will be triggered every time the tied handle is printed towith the \f(CW\*(C`print()\*(C'\fR function.Beyond its self reference it also expects the list that was passed tothe print function..Sp.Vb 1\& sub PRINT { $r = shift; $$r++; print join($,,map(uc($_),@_)),$\e }.Ve.IP "\s-1PRINTF\s0 this, \s-1LIST\s0" 4.IX Xref "PRINTF".IX Item "PRINTF this, LIST"This method will be triggered every time the tied handle is printed towith the \f(CW\*(C`printf()\*(C'\fR function.Beyond its self reference it also expects the format and list that waspassed to the printf function..Sp.Vb 5\& sub PRINTF {\& shift;\& my $fmt = shift;\& print sprintf($fmt, @_);\& }.Ve.IP "\s-1READ\s0 this, \s-1LIST\s0" 4.IX Xref "READ".IX Item "READ this, LIST"This method will be called when the handle is read from via the \f(CW\*(C`read\*(C'\fRor \f(CW\*(C`sysread\*(C'\fR functions..Sp.Vb 8\& sub READ {\& my $self = shift;\& my $bufref = \e$_[0];\& my(undef,$len,$offset) = @_;\& print "READ called, \e$buf=$bufref, \e$len=$len, \e$offset=$offset";\& # add to $$bufref, set $len to number of characters read\& $len;\& }.Ve.IP "\s-1READLINE\s0 this" 4.IX Xref "READLINE".IX Item "READLINE this"This method will be called when the handle is read from via <\s-1HANDLE\s0>.The method should return undef when there is no more data..Sp.Vb 1\& sub READLINE { $r = shift; "READLINE called $$r times\en"; }.Ve.IP "\s-1GETC\s0 this" 4.IX Xref "GETC".IX Item "GETC this"This method will be called when the \f(CW\*(C`getc\*(C'\fR function is called..Sp.Vb 1\& sub GETC { print "Don\*(Aqt GETC, Get Perl"; return "a"; }.Ve.IP "\s-1CLOSE\s0 this" 4.IX Xref "CLOSE".IX Item "CLOSE this"This method will be called when the handle is closed via the \f(CW\*(C`close\*(C'\fRfunction..Sp.Vb 1\& sub CLOSE { print "CLOSE called.\en" }.Ve.IP "\s-1UNTIE\s0 this" 4.IX Xref "UNTIE".IX Item "UNTIE this"As with the other types of ties, this method will be called when \f(CW\*(C`untie\*(C'\fR happens.It may be appropriate to \*(L"auto \s-1CLOSE\s0\*(R" when this occurs. See"The \f(CW\*(C`untie\*(C'\fR Gotcha" below..IP "\s-1DESTROY\s0 this" 4.IX Xref "DESTROY".IX Item "DESTROY this"As with the other types of ties, this method will be called when thetied handle is about to be destroyed. This is useful for debugging andpossibly cleaning up..Sp.Vb 1\& sub DESTROY { print "</shout>\en" }.Ve.PPHere's how to use our little example:.PP.Vb 5\& tie(*FOO,\*(AqShout\*(Aq);\& print FOO "hello\en";\& $a = 4; $b = 6;\& print FOO $a, " plus ", $b, " equals ", $a + $b, "\en";\& print <FOO>;.Ve.Sh "\s-1UNTIE\s0 this".IX Xref "UNTIE".IX Subsection "UNTIE this"You can define for all tie types an \s-1UNTIE\s0 method that will be calledat \fIuntie()\fR. See "The \f(CW\*(C`untie\*(C'\fR Gotcha" below..ie n .Sh "The ""untie"" Gotcha".el .Sh "The \f(CWuntie\fP Gotcha".IX Xref "untie".IX Subsection "The untie Gotcha"If you intend making use of the object returned from either \fItie()\fR or\&\fItied()\fR, and if the tie's target class defines a destructor, there is asubtle gotcha you \fImust\fR guard against..PPAs setup, consider this (admittedly rather contrived) example of atie; all it does is use a file to keep a log of the values assigned toa scalar..PP.Vb 1\& package Remember;\&\& use strict;\& use warnings;\& use IO::File;\&\& sub TIESCALAR {\& my $class = shift;\& my $filename = shift;\& my $handle = IO::File\->new( "> $filename" )\& or die "Cannot open $filename: $!\en";\&\& print $handle "The Start\en";\& bless {FH => $handle, Value => 0}, $class;\& }\&\& sub FETCH {\& my $self = shift;\& return $self\->{Value};\& }\&\& sub STORE {\& my $self = shift;\& my $value = shift;\& my $handle = $self\->{FH};\& print $handle "$value\en";\& $self\->{Value} = $value;\& }\&\& sub DESTROY {\& my $self = shift;\& my $handle = $self\->{FH};\& print $handle "The End\en";\& close $handle;\& }\&\& 1;.Ve.PPHere is an example that makes use of this tie:.PP.Vb 2\& use strict;\& use Remember;\&\& my $fred;\& tie $fred, \*(AqRemember\*(Aq, \*(Aqmyfile.txt\*(Aq;\& $fred = 1;\& $fred = 4;\& $fred = 5;\& untie $fred;\& system "cat myfile.txt";.Ve.PPThis is the output when it is executed:.PP.Vb 5\& The Start\& 1\& 4\& 5\& The End.Ve.PPSo far so good. Those of you who have been paying attention will havespotted that the tied object hasn't been used so far. So lets add anextra method to the Remember class to allow comments to be included inthe file \*(-- say, something like this:.PP.Vb 6\& sub comment {\& my $self = shift;\& my $text = shift;\& my $handle = $self\->{FH};\& print $handle $text, "\en";\& }.Ve.PPAnd here is the previous example modified to use the \f(CW\*(C`comment\*(C'\fR method(which requires the tied object):.PP.Vb 2\& use strict;\& use Remember;\&\& my ($fred, $x);\& $x = tie $fred, \*(AqRemember\*(Aq, \*(Aqmyfile.txt\*(Aq;\& $fred = 1;\& $fred = 4;\& comment $x "changing...";\& $fred = 5;\& untie $fred;\& system "cat myfile.txt";.Ve.PPWhen this code is executed there is no output. Here's why:.PPWhen a variable is tied, it is associated with the object which is thereturn value of the \s-1TIESCALAR\s0, \s-1TIEARRAY\s0, or \s-1TIEHASH\s0 function. Thisobject normally has only one reference, namely, the implicit referencefrom the tied variable. When \fIuntie()\fR is called, that reference isdestroyed. Then, as in the first example above, the object'sdestructor (\s-1DESTROY\s0) is called, which is normal for objects that haveno more valid references; and thus the file is closed..PPIn the second example, however, we have stored another reference tothe tied object in \f(CW$x\fR. That means that when \fIuntie()\fR gets calledthere will still be a valid reference to the object in existence, sothe destructor is not called at that time, and thus the file is notclosed. The reason there is no output is because the file buffershave not been flushed to disk..PPNow that you know what the problem is, what can you do to avoid it?Prior to the introduction of the optional \s-1UNTIE\s0 method the only waywas the good old \f(CW\*(C`\-w\*(C'\fR flag. Which will spot any instances where you call\&\fIuntie()\fR and there are still valid references to the tied object. Ifthe second script above this near the top \f(CW\*(C`use warnings \*(Aquntie\*(Aq\*(C'\fRor was run with the \f(CW\*(C`\-w\*(C'\fR flag, Perl prints thiswarning message:.PP.Vb 1\& untie attempted while 1 inner references still exist.Ve.PPTo get the script to work properly and silence the warning make surethere are no valid references to the tied object \fIbefore\fR \fIuntie()\fR iscalled:.PP.Vb 2\& undef $x;\& untie $fred;.Ve.PPNow that \s-1UNTIE\s0 exists the class designer can decide which parts of theclass functionality are really associated with \f(CW\*(C`untie\*(C'\fR and which withthe object being destroyed. What makes sense for a given class dependson whether the inner references are being kept so that non-tie-relatedmethods can be called on the object. But in most cases it probably makessense to move the functionality that would have been in \s-1DESTROY\s0 to the \s-1UNTIE\s0method..PPIf the \s-1UNTIE\s0 method exists then the warning above does not occur. Instead the\&\s-1UNTIE\s0 method is passed the count of \*(L"extra\*(R" references and can issue its ownwarning if appropriate. e.g. to replicate the no \s-1UNTIE\s0 case this method canbe used:.PP.Vb 5\& sub UNTIE\& {\& my ($obj,$count) = @_;\& carp "untie attempted while $count inner references still exist" if $count;\& }.Ve.SH "SEE ALSO".IX Header "SEE ALSO"See DB_File or Config for some interesting \fItie()\fR implementations.A good starting point for many \fItie()\fR implementations is with one of themodules Tie::Scalar, Tie::Array, Tie::Hash, or Tie::Handle..SH "BUGS".IX Header "BUGS"The bucket usage information provided by \f(CW\*(C`scalar(%hash)\*(C'\fR is notavailable. What this means is that using \f(CW%tied_hash\fR in booleancontext doesn't work right (currently this always tests false,regardless of whether the hash is empty or hash elements)..PPLocalizing tied arrays or hashes does not work. After exiting thescope the arrays or the hashes are not restored..PPCounting the number of entries in a hash via \f(CW\*(C`scalar(keys(%hash))\*(C'\fRor \f(CW\*(C`scalar(values(%hash)\*(C'\fR) is inefficient since it needs to iteratethrough all the entries with \s-1FIRSTKEY/NEXTKEY\s0..PPTied hash/array slices cause multiple \s-1FETCH/STORE\s0 pairs, there are notie methods for slice operations..PPYou cannot easily tie a multilevel data structure (such as a hash ofhashes) to a dbm file. The first problem is that all but \s-1GDBM\s0 andBerkeley \s-1DB\s0 have size limitations, but beyond that, you also have problemswith how references are to be represented on disk. One experimentalmodule that does attempt to address this need is DBM::Deep. Check yournearest \s-1CPAN\s0 site as described in perlmodlib for source code. Notethat despite its name, DBM::Deep does not use dbm. Another earlier attemptat solving the problem is \s-1MLDBM\s0, which is also available on the \s-1CPAN\s0, butwhich has some fairly serious limitations..PPTied filehandles are still incomplete. \fIsysopen()\fR, \fItruncate()\fR,\&\fIflock()\fR, \fIfcntl()\fR, \fIstat()\fR and \-X can't currently be trapped..SH "AUTHOR".IX Header "AUTHOR"Tom Christiansen.PP\&\s-1TIEHANDLE\s0 by Sven Verdoolaege <\fIskimo@dns.ufsia.ac.be\fR> and Doug MacEachern <\fIdougm@osf.org\fR>.PP\&\s-1UNTIE\s0 by Nick Ing-Simmons <\fInick@ing\-simmons.net\fR>.PP\&\s-1SCALAR\s0 by Tassilo von Parseval <\fItassilo.von.parseval@rwth\-aachen.de\fR>.PPTying Arrays by Casey West <\fIcasey@geeknest.com\fR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -