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

📄 perltie.pod

📁 MSYS在windows下模拟了一个类unix的终端
💻 POD
📖 第 1 页 / 共 3 页
字号:
	return exists $self->{LIST}->{$dot};    }=item FIRSTKEY thisThis method will be triggered when the user is goingto iterate through the hash, such as via a keys() or each()call.    sub FIRSTKEY {	carp &whowasi if $DEBUG;	my $self = shift;	my $a = keys %{$self->{LIST}};		# reset each() iterator	each %{$self->{LIST}}    }=item NEXTKEY this, lastkeyThis method gets triggered during a keys() or each() iteration.  It has asecond argument which is the last key that had been accessed.  This isuseful if you're carrying about ordering or calling the iterator from morethan one sequence, or not really storing things in a hash anywhere.For our example, we're using a real hash so we'll do just the simplething, but we'll have to go through the LIST field indirectly.    sub NEXTKEY  {	carp &whowasi if $DEBUG;	my $self = shift;	return each %{ $self->{LIST} }    }=item UNTIE thisThis is called when C<untie> occurs.=item DESTROY thisThis method is triggered when a tied hash is about to go out ofscope.  You don't really need it unless you're trying to add debuggingor have auxiliary state to clean up.  Here's a very simple function:    sub DESTROY  {	carp &whowasi if $DEBUG;    }=backNote that functions such as keys() and values() may return huge listswhen used on large objects, like DBM files.  You may prefer to use theeach() function to iterate over such.  Example:    # print out history file offsets    use NDBM_File;    tie(%HIST, 'NDBM_File', '/usr/lib/news/history', 1, 0);    while (($key,$val) = each %HIST) {        print $key, ' = ', unpack('L',$val), "\n";    }    untie(%HIST);=head2 Tying FileHandlesThis is partially implemented now.A class implementing a tied filehandle should define the followingmethods: TIEHANDLE, at least one of PRINT, PRINTF, WRITE, READLINE, GETC,READ, and possibly CLOSE, UNTIE and DESTROY.  The class can also provide: BINMODE,OPEN, EOF, FILENO, SEEK, TELL - if the corresponding perl operators areused on the handle.It is especially useful when perl is embedded in some other program,where output to STDOUT and STDERR may have to be redirected in somespecial way. See nvi and the Apache module for examples.In our example we're going to create a shouting handle.    package Shout;=over 4=item TIEHANDLE classname, LISTThis 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.    sub TIEHANDLE { print "<shout>\n"; my $i; bless \$i, shift }=item WRITE this, LISTThis method will be called when the handle is written to via theC<syswrite> function.    sub WRITE {	$r = shift;	my($buf,$len,$offset) = @_;	print "WRITE called, \$buf=$buf, \$len=$len, \$offset=$offset";    }=item PRINT this, LISTThis method will be triggered every time the tied handle is printed towith the C<print()> function.Beyond its self reference it also expects the list that was passed tothe print function.    sub PRINT { $r = shift; $$r++; print join($,,map(uc($_),@_)),$\ }=item PRINTF this, LISTThis method will be triggered every time the tied handle is printed towith the C<printf()> function.Beyond its self reference it also expects the format and list that waspassed to the printf function.    sub PRINTF {        shift;        my $fmt = shift;        print sprintf($fmt, @_)."\n";    }=item READ this, LISTThis method will be called when the handle is read from via the C<read>or C<sysread> functions.    sub READ {	my $self = shift;	my $$bufref = \$_[0];	my(undef,$len,$offset) = @_;	print "READ called, \$buf=$bufref, \$len=$len, \$offset=$offset";	# add to $$bufref, set $len to number of characters read	$len;    }=item READLINE thisThis method will be called when the handle is read from via <HANDLE>.The method should return undef when there is no more data.    sub READLINE { $r = shift; "READLINE called $$r times\n"; }=item GETC thisThis method will be called when the C<getc> function is called.    sub GETC { print "Don't GETC, Get Perl"; return "a"; }=item CLOSE thisThis method will be called when the handle is closed via the C<close>function.    sub CLOSE { print "CLOSE called.\n" }=item UNTIE thisAs with the other types of ties, this method will be called when C<untie> happens.It may be appropriate to "auto CLOSE" when this occurs.=item DESTROY thisAs 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.    sub DESTROY { print "</shout>\n" }=backHere's how to use our little example:    tie(*FOO,'Shout');    print FOO "hello\n";    $a = 4; $b = 6;    print FOO $a, " plus ", $b, " equals ", $a + $b, "\n";    print <FOO>;=head2 UNTIE thisYou can define for all tie types an UNTIE method that will be calledat untie().=head2 The C<untie> GotchaIf you intend making use of the object returned from either tie() ortied(), and if the tie's target class defines a destructor, there is asubtle gotcha you I<must> guard against.As 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.    package Remember;    use strict;    use warnings;    use IO::File;    sub TIESCALAR {        my $class = shift;        my $filename = shift;        my $handle = new IO::File "> $filename"                         or die "Cannot open $filename: $!\n";        print $handle "The Start\n";        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\n";        $self->{Value} = $value;    }    sub DESTROY {        my $self = shift;        my $handle = $self->{FH};        print $handle "The End\n";        close $handle;    }    1;Here is an example that makes use of this tie:    use strict;    use Remember;    my $fred;    tie $fred, 'Remember', 'myfile.txt';    $fred = 1;    $fred = 4;    $fred = 5;    untie $fred;    system "cat myfile.txt";This is the output when it is executed:    The Start    1    4    5    The EndSo 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:    sub comment {        my $self = shift;        my $text = shift;        my $handle = $self->{FH};        print $handle $text, "\n";    }And here is the previous example modified to use the C<comment> method(which requires the tied object):    use strict;    use Remember;    my ($fred, $x);    $x = tie $fred, 'Remember', 'myfile.txt';    $fred = 1;    $fred = 4;    comment $x "changing...";    $fred = 5;    untie $fred;    system "cat myfile.txt";When this code is executed there is no output.  Here's why:When a variable is tied, it is associated with the object which is thereturn value of the TIESCALAR, TIEARRAY, or TIEHASH function.  Thisobject normally has only one reference, namely, the implicit referencefrom the tied variable.  When untie() is called, that reference isdestroyed.  Then, as in the first example above, the object'sdestructor (DESTROY) is called, which is normal for objects that haveno more valid references; and thus the file is closed.In the second example, however, we have stored another reference tothe tied object in $x.  That means that when untie() 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.Now that you know what the problem is, what can you do to avoid it?Prior to the introduction of the optional UNTIE method the only waywas the good old C<-w> flag. Which will spot any instances where you calluntie() and there are still valid references to the tied object.  Ifthe second script above this near the top C<use warnings 'untie'>or was run with the C<-w> flag, Perl prints thiswarning message:    untie attempted while 1 inner references still existTo get the script to work properly and silence the warning make surethere are no valid references to the tied object I<before> untie() iscalled:    undef $x;    untie $fred;Now that UNTIE exists the class designer can decide which parts of theclass functionality are really associated with C<untie> 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 DESTROY to the UNTIEmethod.If the UNTIE method exists then the warning above does not occur. Instead theUNTIE method is passed the count of "extra" references and can issue its ownwarning if appropriate. e.g. to replicate the no UNTIE case this method canbe used:    sub UNTIE    {     my ($obj,$count) = @_;     carp "untie attempted while $count inner references still exist" if $count;    }=head1 SEE ALSOSee L<DB_File> or L<Config> for some interesting tie() implementations.A good starting point for many tie() implementations is with one of themodules L<Tie::Scalar>, L<Tie::Array>, L<Tie::Hash>, or L<Tie::Handle>.=head1 BUGSYou cannot easily tie a multilevel data structure (such as a hash ofhashes) to a dbm file.  The first problem is that all but GDBM andBerkeley DB 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 partially is the MLDBMmodule.  Check your nearest CPAN site as described in L<perlmodlib> forsource code to MLDBM.Tied filehandles are still incomplete.  sysopen(), truncate(),flock(), fcntl(), stat() and -X can't currently be trapped.=head1 AUTHORTom ChristiansenTIEHANDLE by Sven Verdoolaege <F<skimo@dns.ufsia.ac.be>> and Doug MacEachern <F<dougm@osf.org>>UNTIE by Nick Ing-Simmons <F<nick@ing-simmons.net>>Tying Arrays by Casey Tweten <F<crt@kiski.net>>

⌨️ 快捷键说明

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