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

📄 perltoot.1

📁 视频监控网络部分的协议ddns,的模块的实现代码,请大家大胆指正.
💻 1
📖 第 1 页 / 共 5 页
字号:
.PP.Vb 5\&    sub salary {\&        my $self = shift;\&        if (@_) { $self\->{SALARY} = shift }\&        return $self\->{SALARY};\&    }\&\&    sub id_number {\&        my $self = shift;\&        if (@_) { $self\->{ID} = shift }\&        return $self\->{ID};\&    }\&\&    sub start_date {\&        my $self = shift;\&        if (@_) { $self\->{START_DATE} = shift }\&        return $self\->{START_DATE};\&    }.Ve.Sh "Overridden Methods".IX Subsection "Overridden Methods"What happens when both a derived class and its base class have the samemethod defined?  Well, then you get the derived class's version of thatmethod.  For example, let's say that we want the \fIpeers()\fR method called onan employee to act a bit differently.  Instead of just returning the listof peer names, let's return slightly different strings.  So doing this:.PP.Vb 2\&    $empl\->peers("Peter", "Paul", "Mary");\&    printf "His peers are: %s\en", join(", ", $empl\->peers);.Ve.PPwill produce:.PP.Vb 1\&    His peers are: PEON=PETER, PEON=PAUL, PEON=MARY.Ve.PPTo do this, merely add this definition into the Employee.pm file:.PP.Vb 5\&    sub peers {\&        my $self = shift;\&        if (@_) { @{ $self\->{PEERS} } = @_ }\&        return map { "PEON=\eU$_" } @{ $self\->{PEERS} };\&    }.Ve.PPThere, we've just demonstrated the high\-falutin' concept known in certaincircles as \fIpolymorphism\fR.  We've taken on the form and behaviour ofan existing object, and then we've altered it to suit our own purposes.This is a form of Laziness.  (Getting polymorphed is also what happenswhen the wizard decides you'd look better as a frog.).PPEvery now and then you'll want to have a method call trigger both itsderived class (also known as \*(L"subclass\*(R") version as well as its base class(also known as \*(L"superclass\*(R") version.  In practice, constructors anddestructors are likely to want to do this, and it probably also makessense in the \fIdebug()\fR method we showed previously..PPTo do this, add this to Employee.pm:.PP.Vb 2\&    use Carp;\&    my $Debugging = 0;\&\&    sub debug {\&        my $self = shift;\&        confess "usage: thing\->debug(level)"    unless @_ == 1;\&        my $level = shift;\&        if (ref($self))  {\&            $self\->{"_DEBUG"} = $level;\&        } else {\&            $Debugging = $level;            # whole class\&        }\&        Person::debug($self, $Debugging);   # don\*(Aqt really do this\&    }.Ve.PPAs you see, we turn around and call the Person package's \fIdebug()\fR function.But this is far too fragile for good design.  What if Person doesn'thave a \fIdebug()\fR function, but is inheriting \fIits\fR \fIdebug()\fR methodfrom elsewhere?  It would have been slightly better to say.PP.Vb 1\&    Person\->debug($Debugging);.Ve.PPBut even that's got too much hard-coded.  It's somewhat better to say.PP.Vb 1\&    $self\->Person::debug($Debugging);.Ve.PPWhich is a funny way to say to start looking for a \fIdebug()\fR method upin Person.  This strategy is more often seen on overridden object methodsthan on overridden class methods..PPThere is still something a bit off here.  We've hard-coded oursuperclass's name.  This in particular is bad if you change which classesyou inherit from, or add others.  Fortunately, the pseudoclass \s-1SUPER\s0comes to the rescue here..PP.Vb 1\&    $self\->SUPER::debug($Debugging);.Ve.PPThis way it starts looking in my class's \f(CW@ISA\fR.  This only makes sensefrom \fIwithin\fR a method call, though.  Don't try to access anythingin \s-1SUPER::\s0 from anywhere else, because it doesn't exist outsidean overridden method call. Note that \f(CW\*(C`SUPER\*(C'\fR refers to the superclass ofthe current package, \fInot\fR to the superclass of \f(CW$self\fR..PPThings are getting a bit complicated here.  Have we done anythingwe shouldn't?  As before, one way to test whether we're designinga decent class is via the empty subclass test.  Since we already havean Employee class that we're trying to check, we'd better get a newempty subclass that can derive from Employee.  Here's one:.PP.Vb 3\&    package Boss;\&    use Employee;        # :\-)\&    @ISA = qw(Employee);.Ve.PPAnd here's the test program:.PP.Vb 4\&    #!/usr/bin/perl \-w\&    use strict;\&    use Boss;\&    Boss\->debug(1);\&\&    my $boss = Boss\->new();\&\&    $boss\->fullname\->title("Don");\&    $boss\->fullname\->surname("Pichon Alvarez");\&    $boss\->fullname\->christian("Federico Jesus");\&    $boss\->fullname\->nickname("Fred");\&\&    $boss\->age(47);\&    $boss\->peers("Frank", "Felipe", "Faust");\&\&    printf "%s is age %d.\en", $boss\->fullname\->as_string, $boss\->age;\&    printf "His peers are: %s\en", join(", ", $boss\->peers);.Ve.PPRunning it, we see that we're still ok.  If you'd like to dump out yourobject in a nice format, somewhat like the way the 'x' command works inthe debugger, you could use the Data::Dumper module from \s-1CPAN\s0 this way:.PP.Vb 3\&    use Data::Dumper;\&    print "Here\*(Aqs the boss:\en";\&    print Dumper($boss);.Ve.PPWhich shows us something like this:.PP.Vb 10\&    Here\*(Aqs the boss:\&    $VAR1 = bless( {\&         _CENSUS => \e1,\&         FULLNAME => bless( {\&                              TITLE => \*(AqDon\*(Aq,\&                              SURNAME => \*(AqPichon Alvarez\*(Aq,\&                              NICK => \*(AqFred\*(Aq,\&                              CHRISTIAN => \*(AqFederico Jesus\*(Aq\&                            }, \*(AqFullname\*(Aq ),\&         AGE => 47,\&         PEERS => [\&                    \*(AqFrank\*(Aq,\&                    \*(AqFelipe\*(Aq,\&                    \*(AqFaust\*(Aq\&                  ]\&       }, \*(AqBoss\*(Aq );.Ve.PPHm.... something's missing there.  What about the salary, start date,and \s-1ID\s0 fields?  Well, we never set them to anything, even undef, so theydon't show up in the hash's keys.  The Employee class has no \fInew()\fR methodof its own, and the \fInew()\fR method in Person doesn't know about Employees.(Nor should it: proper \s-1OO\s0 design dictates that a subclass be allowed toknow about its immediate superclass, but never vice-versa.)  So let'sfix up \fIEmployee::new()\fR this way:.PP.Vb 9\&    sub new {\&        my $class = shift;\&        my $self  = $class\->SUPER::new();\&        $self\->{SALARY}        = undef;\&        $self\->{ID}            = undef;\&        $self\->{START_DATE}    = undef;\&        bless ($self, $class);          # reconsecrate\&        return $self;\&    }.Ve.PPNow if you dump out an Employee or Boss object, you'll findthat new fields show up there now..Sh "Multiple Inheritance".IX Subsection "Multiple Inheritance"Ok, at the risk of confusing beginners and annoying \s-1OO\s0 gurus, it'stime to confess that Perl's object system includes that controversialnotion known as multiple inheritance, or \s-1MI\s0 for short.  All this meansis that rather than having just one parent class who in turn mightitself have a parent class, etc., that you can directly inherit fromtwo or more parents.  It's true that some uses of \s-1MI\s0 can get you intotrouble, although hopefully not quite so much trouble with Perl as withdubiously-OO languages like \*(C+..PPThe way it works is actually pretty simple: just put more than one packagename in your \f(CW@ISA\fR array.  When it comes time for Perl to go findingmethods for your object, it looks at each of these packages in order.Well, kinda.  It's actually a fully recursive, depth-first order bydefault (see mro for alternate method resolution orders).Consider a bunch of \f(CW@ISA\fR arrays like this:.PP.Vb 3\&    @First::ISA    = qw( Alpha );\&    @Second::ISA   = qw( Beta );\&    @Third::ISA    = qw( First Second );.Ve.PPIf you have an object of class Third:.PP.Vb 2\&    my $ob = Third\->new();\&    $ob\->spin();.Ve.PPHow do we find a \fIspin()\fR method (or a \fInew()\fR method for that matter)?Because the search is depth-first, classes will be looked upin the following order: Third, First, Alpha, Second, and Beta..PPIn practice, few class modules have been seen that actuallymake use of \s-1MI\s0.  One nearly always chooses simple containership ofone class within another over \s-1MI\s0.  That's why our Personobject \fIcontained\fR a Fullname object.  That doesn't meanit \fIwas\fR one..PPHowever, there is one particular area where \s-1MI\s0 in Perl is rampant:borrowing another class's class methods.  This is rather common,especially with some bundled \*(L"objectless\*(R" classes,like Exporter, DynaLoader, AutoLoader, and SelfLoader.  These classesdo not provide constructors; they exist only so you may inherit theirclass methods.  (It's not entirely clear why inheritance was donehere rather than traditional module importation.).PPFor example, here is the \s-1POSIX\s0 module's \f(CW@ISA:\fR.PP.Vb 2\&    package POSIX;\&    @ISA = qw(Exporter DynaLoader);.Ve.PPThe \s-1POSIX\s0 module isn't really an object module, but then,neither are Exporter or DynaLoader.  They're just lending theirclasses' behaviours to \s-1POSIX\s0..PPWhy don't people use \s-1MI\s0 for object methods much?  One reason is thatit can have complicated side-effects.  For one thing, your inheritancegraph (no longer a tree) might converge back to the same base class.Although Perl guards against recursive inheritance, merely having parentswho are related to each other via a common ancestor, incestuous thoughit sounds, is not forbidden.  What if in our Third class shown above wewanted its \fInew()\fR method to also call both overridden constructors in itstwo parent classes?  The \s-1SUPER\s0 notation would only find the first one.Also, what about if the Alpha and Beta classes both had a common ancestor,like Nought?  If you kept climbing up the inheritance tree callingoverridden methods, you'd end up calling \fINought::new()\fR twice,which might well be a bad idea..Sh "\s-1UNIVERSAL:\s0 The Root of All Objects".IX Subsection "UNIVERSAL: The Root of All Objects"Wouldn't it be convenient if all objects were rooted at some ultimatebase class?  That way you could give every object common methods withouthaving to go and add it to each and every \f(CW@ISA\fR.  Well, it turns out thatyou can.  You don't see it, but Perl tacitly and irrevocably assumesthat there's an extra element at the end of \f(CW@ISA:\fR the class \s-1UNIVERSAL\s0.In version 5.003, there were no predefined methods there, but you could putwhatever you felt like into it..PPHowever, as of version 5.004 (or some subversive releases, like 5.003_08),\&\s-1UNIVERSAL\s0 has some methods in it already.  These are builtin to your Perlbinary, so they don't take any extra time to load.  Predefined methodsinclude \fIisa()\fR, \fIcan()\fR, and \s-1\fIVERSION\s0()\fR.  \fIisa()\fR tells you whether an object orclass \*(L"is\*(R" another one without having to traverse the hierarchy yourself:.PP.Vb 2\&   $has_io = $fd\->isa("IO::Handle");\&   $itza_handle = IO::Socket\->isa("IO::Handle");.Ve.PPThe \fIcan()\fR method, called against that object or class, reports backwhether its string argument is a callable method name in that class.In fact, it gives you back a function reference to that method:.PP.Vb 1\&   $his_print_method = $obj\->can(\*(Aqas_string\*(Aq);.Ve.PPFinally, the \s-1VERSION\s0 method checks whether the class (or the object'sclass) has a package global called \f(CW$VERSION\fR that's high enough, as in:.PP.Vb 2\&    Some_Module\->VERSION(3.0);\&    $his_vers = $ob\->VERSION();.Ve.PPHowever, we don't usually call \s-1VERSION\s0 ourselves.  (Remember that an alluppercase function name is a Perl convention that indicates that thefunction will be automatically used by Perl in some way.)  In this case,it happens when you say.PP.Vb 1\&    use Some_Module 3.0;.Ve.PPIf you wanted to add version checking to your Person class explainedabove, just add this to Person.pm:.PP.Vb 1\&    our $VERSION = \*(Aq1.1\*(Aq;.Ve.PPand then in Employee.pm you can say.PP.Vb 1\&    use Person 1.1;.Ve.PPAnd it would make sure that you have at least that version number orhigher available.   This is not the same as loading in that exact versionnumber.  No mechanism currently exists for concurrent installation of

⌨️ 快捷键说明

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