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

📄 perltie.1

📁 视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.
💻 1
📖 第 1 页 / 共 4 页
字号:
\&            $f, length $him{$f};\&    }.Ve.PPIn our tied hash DotFiles example, we use a regularhash for the object containing several importantfields, of which only the \f(CW\*(C`{LIST}\*(C'\fR field will be what theuser thinks of as the real hash..IP "\s-1USER\s0" 5.IX Item "USER"whose dot files this object represents.IP "\s-1HOME\s0" 5.IX Item "HOME"where those dot files live.IP "\s-1CLOBBER\s0" 5.IX Item "CLOBBER"whether we should try to change or remove those dot files.IP "\s-1LIST\s0" 5.IX Item "LIST"the hash of dot file names and content mappings.PPHere's the start of \fIDotfiles.pm\fR:.PP.Vb 5\&    package DotFiles;\&    use Carp;\&    sub whowasi { (caller(1))[3] . \*(Aq()\*(Aq }\&    my $DEBUG = 0;\&    sub debug { $DEBUG = @_ ? shift : 1 }.Ve.PPFor our example, we want to be able to emit debugging info to help in tracingduring development.  We keep also one convenience function aroundinternally to help print out warnings; \fIwhowasi()\fR returns the function namethat calls it..PPHere are the methods for the DotFiles tied hash..IP "\s-1TIEHASH\s0 classname, \s-1LIST\s0" 4.IX Xref "TIEHASH".IX Item "TIEHASH classname, LIST"This is the constructor for the class.  That means it is expected toreturn a blessed reference through which the new object (probably but notnecessarily an anonymous hash) will be accessed..SpHere's the constructor:.Sp.Vb 9\&    sub TIEHASH {\&        my $self = shift;\&        my $user = shift || $>;\&        my $dotdir = shift || \*(Aq\*(Aq;\&        croak "usage: @{[&whowasi]} [USER [DOTDIR]]" if @_;\&        $user = getpwuid($user) if $user =~ /^\ed+$/;\&        my $dir = (getpwnam($user))[7]\&                || croak "@{[&whowasi]}: no user $user";\&        $dir .= "/$dotdir" if $dotdir;\&\&        my $node = {\&            USER    => $user,\&            HOME    => $dir,\&            LIST    => {},\&            CLOBBER => 0,\&        };\&\&        opendir(DIR, $dir)\&                || croak "@{[&whowasi]}: can\*(Aqt opendir $dir: $!";\&        foreach $dot ( grep /^\e./ && \-f "$dir/$_", readdir(DIR)) {\&            $dot =~ s/^\e.//;\&            $node\->{LIST}{$dot} = undef;\&        }\&        closedir DIR;\&        return bless $node, $self;\&    }.Ve.SpIt's probably worth mentioning that if you're going to filetest thereturn values out of a readdir, you'd better prepend the directoryin question.  Otherwise, because we didn't \fIchdir()\fR there, it wouldhave been testing the wrong file..IP "\s-1FETCH\s0 this, key" 4.IX Xref "FETCH".IX Item "FETCH this, key"This method will be triggered every time an element in the tied hash isaccessed (read).  It takes one argument beyond its self reference: the keywhose value we're trying to fetch..SpHere's the fetch for our DotFiles example..Sp.Vb 6\&    sub FETCH {\&        carp &whowasi if $DEBUG;\&        my $self = shift;\&        my $dot = shift;\&        my $dir = $self\->{HOME};\&        my $file = "$dir/.$dot";\&\&        unless (exists $self\->{LIST}\->{$dot} || \-f $file) {\&            carp "@{[&whowasi]}: no $dot file" if $DEBUG;\&            return undef;\&        }\&\&        if (defined $self\->{LIST}\->{$dot}) {\&            return $self\->{LIST}\->{$dot};\&        } else {\&            return $self\->{LIST}\->{$dot} = \`cat $dir/.$dot\`;\&        }\&    }.Ve.SpIt was easy to write by having it call the Unix \fIcat\fR\|(1) command, but itwould probably be more portable to open the file manually (and somewhatmore efficient).  Of course, because dot files are a Unixy concept, we'renot that concerned..IP "\s-1STORE\s0 this, key, value" 4.IX Xref "STORE".IX Item "STORE this, key, value"This method will be triggered every time an element in the tied hash is set(written).  It takes two arguments beyond its self reference: the index atwhich we're trying to store something, and the value we're trying to putthere..SpHere in our DotFiles example, we'll be careful not to letthem try to overwrite the file unless they've called the \fIclobber()\fRmethod on the original object reference returned by \fItie()\fR..Sp.Vb 7\&    sub STORE {\&        carp &whowasi if $DEBUG;\&        my $self = shift;\&        my $dot = shift;\&        my $value = shift;\&        my $file = $self\->{HOME} . "/.$dot";\&        my $user = $self\->{USER};\&\&        croak "@{[&whowasi]}: $file not clobberable"\&            unless $self\->{CLOBBER};\&\&        open(F, "> $file") || croak "can\*(Aqt open $file: $!";\&        print F $value;\&        close(F);\&    }.Ve.SpIf they wanted to clobber something, they might say:.Sp.Vb 3\&    $ob = tie %daemon_dots, \*(Aqdaemon\*(Aq;\&    $ob\->clobber(1);\&    $daemon_dots{signature} = "A true daemon\en";.Ve.SpAnother way to lay hands on a reference to the underlying object is touse the \fItied()\fR function, so they might alternately have set clobberusing:.Sp.Vb 2\&    tie %daemon_dots, \*(Aqdaemon\*(Aq;\&    tied(%daemon_dots)\->clobber(1);.Ve.SpThe clobber method is simply:.Sp.Vb 4\&    sub clobber {\&        my $self = shift;\&        $self\->{CLOBBER} = @_ ? shift : 1;\&    }.Ve.IP "\s-1DELETE\s0 this, key" 4.IX Xref "DELETE".IX Item "DELETE this, key"This method is triggered when we remove an element from the hash,typically by using the \fIdelete()\fR function.  Again, we'llbe careful to check whether they really want to clobber files..Sp.Vb 2\&    sub DELETE   {\&        carp &whowasi if $DEBUG;\&\&        my $self = shift;\&        my $dot = shift;\&        my $file = $self\->{HOME} . "/.$dot";\&        croak "@{[&whowasi]}: won\*(Aqt remove file $file"\&            unless $self\->{CLOBBER};\&        delete $self\->{LIST}\->{$dot};\&        my $success = unlink($file);\&        carp "@{[&whowasi]}: can\*(Aqt unlink $file: $!" unless $success;\&        $success;\&    }.Ve.SpThe value returned by \s-1DELETE\s0 becomes the return value of the callto \fIdelete()\fR.  If you want to emulate the normal behavior of \fIdelete()\fR,you should return whatever \s-1FETCH\s0 would have returned for this key.In this example, we have chosen instead to return a value which tellsthe caller whether the file was successfully deleted..IP "\s-1CLEAR\s0 this" 4.IX Xref "CLEAR".IX Item "CLEAR this"This method is triggered when the whole hash is to be cleared, usually byassigning the empty list to it..SpIn our example, that would remove all the user's dot files!  It's such adangerous thing that they'll have to set \s-1CLOBBER\s0 to something higher than1 to make it happen..Sp.Vb 10\&    sub CLEAR    {\&        carp &whowasi if $DEBUG;\&        my $self = shift;\&        croak "@{[&whowasi]}: won\*(Aqt remove all dot files for $self\->{USER}"\&            unless $self\->{CLOBBER} > 1;\&        my $dot;\&        foreach $dot ( keys %{$self\->{LIST}}) {\&            $self\->DELETE($dot);\&        }\&    }.Ve.IP "\s-1EXISTS\s0 this, key" 4.IX Xref "EXISTS".IX Item "EXISTS this, key"This method is triggered when the user uses the \fIexists()\fR functionon a particular hash.  In our example, we'll look at the \f(CW\*(C`{LIST}\*(C'\fRhash element for this:.Sp.Vb 6\&    sub EXISTS   {\&        carp &whowasi if $DEBUG;\&        my $self = shift;\&        my $dot = shift;\&        return exists $self\->{LIST}\->{$dot};\&    }.Ve.IP "\s-1FIRSTKEY\s0 this" 4.IX Xref "FIRSTKEY".IX Item "FIRSTKEY this"This method will be triggered when the user is goingto iterate through the hash, such as via a \fIkeys()\fR or \fIeach()\fRcall..Sp.Vb 6\&    sub FIRSTKEY {\&        carp &whowasi if $DEBUG;\&        my $self = shift;\&        my $a = keys %{$self\->{LIST}};          # reset each() iterator\&        each %{$self\->{LIST}}\&    }.Ve.IP "\s-1NEXTKEY\s0 this, lastkey" 4.IX Xref "NEXTKEY".IX Item "NEXTKEY this, lastkey"This method gets triggered during a \fIkeys()\fR or \fIeach()\fR 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..SpFor our example, we're using a real hash so we'll do just the simplething, but we'll have to go through the \s-1LIST\s0 field indirectly..Sp.Vb 5\&    sub NEXTKEY  {\&        carp &whowasi if $DEBUG;\&        my $self = shift;\&        return each %{ $self\->{LIST} }\&    }.Ve.IP "\s-1SCALAR\s0 this" 4.IX Xref "SCALAR".IX Item "SCALAR this"This is called when the hash is evaluated in scalar context. In orderto mimic the behaviour of untied hashes, this method should return afalse value when the tied hash is considered empty. If this method doesnot exist, perl will make some educated guesses and return true whenthe hash is inside an iteration. If this isn't the case, \s-1FIRSTKEY\s0 iscalled, and the result will be a false value if \s-1FIRSTKEY\s0 returns the emptylist, true otherwise..SpHowever, you should \fBnot\fR blindly rely on perl always doing the right thing. Particularly, perl will mistakenly return true when you clear the hash by repeatedly calling \s-1DELETE\s0 until it is empty. You are therefore advised to supply your own \s-1SCALAR\s0 method when you want to be absolutely sure that your hash behaves nicely in scalar context..SpIn our example we can just call \f(CW\*(C`scalar\*(C'\fR on the underlying hashreferenced by \f(CW\*(C`$self\->{LIST}\*(C'\fR:.Sp.Vb 5\&    sub SCALAR {\&        carp &whowasi if $DEBUG;\&        my $self = shift;\&        return scalar %{ $self\->{LIST} }\&    }.Ve.IP "\s-1UNTIE\s0 this" 4.IX Xref "UNTIE".IX Item "UNTIE this"This is called when \f(CW\*(C`untie\*(C'\fR occurs.  See "The \f(CW\*(C`untie\*(C'\fR Gotcha" below..IP "\s-1DESTROY\s0 this" 4.IX Xref "DESTROY".IX Item "DESTROY this"This 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:.Sp.Vb 3\&    sub DESTROY  {\&        carp &whowasi if $DEBUG;\&    }.Ve.PPNote that functions such as \fIkeys()\fR and \fIvalues()\fR may return huge listswhen used on large objects, like \s-1DBM\s0 files.  You may prefer to use the\&\fIeach()\fR function to iterate over such.  Example:.PP.Vb 7\&    # print out history file offsets\&    use NDBM_File;\&    tie(%HIST, \*(AqNDBM_File\*(Aq, \*(Aq/usr/lib/news/history\*(Aq, 1, 0);\&    while (($key,$val) = each %HIST) {\&        print $key, \*(Aq = \*(Aq, unpack(\*(AqL\*(Aq,$val), "\en";\&    }\&    untie(%HIST);.Ve.Sh "Tying FileHandles".IX Xref "filehandle, tying".IX Subsection "Tying FileHandles"This is partially implemented now..PPA class implementing a tied filehandle should define the followingmethods: \s-1TIEHANDLE\s0, at least one of \s-1PRINT\s0, \s-1PRINTF\s0, \s-1WRITE\s0, \s-1READLINE\s0, \s-1GETC\s0,\&\s-1READ\s0, and possibly \s-1CLOSE\s0, \s-1UNTIE\s0 and \s-1DESTROY\s0.  The class can also provide: \s-1BINMODE\s0,\&\s-1OPEN\s0, \s-1EOF\s0, \s-1FILENO\s0, \s-1SEEK\s0, \s-1TELL\s0 \- if the corresponding perl operators areused on the handle..PPWhen \s-1STDERR\s0 is tied, its \s-1PRINT\s0 method will be called to issue warningsand error messages.  This feature is temporarily disabled during the call, which means you can use \f(CW\*(C`warn()\*(C'\fR inside \s-1PRINT\s0 without starting a recursiveloop.  And just like \f(CW\*(C`_\|_WARN_\|_\*(C'\fR and \f(CW\*(C`_\|_DIE_\|_\*(C'\fR handlers, \s-1STDERR\s0's \s-1PRINT\s0method may be called to report parser errors, so the caveats mentioned under \&\*(L"%SIG\*(R" in perlvar apply..PPAll of this is especially useful when perl is embedded in some other program, where output to \s-1STDOUT\s0 and \s-1STDERR\s0 may have to be redirected 

⌨️ 快捷键说明

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