📄 perlbot.1
字号:
\&\& package Foo;\& @ISA = qw( Bar Baz );\&\& sub new {\& my $type = shift;\& bless [], $type;\& }\& sub grr { print "grumble\en" }\& sub goo {\& my $self = shift;\& $self\->SUPER::goo();\& }\& sub mumble {\& my $self = shift;\& $self\->SUPER::mumble();\& }\& sub google {\& my $self = shift;\& $self\->SUPER::google();\& }\&\& package main;\&\& $foo = Foo\->new;\& $foo\->mumble;\& $foo\->grr;\& $foo\->goo;\& $foo\->google;.Ve.PPNote that \f(CW\*(C`SUPER\*(C'\fR refers to the superclasses of the current package(\f(CW\*(C`Foo\*(C'\fR), not to the superclasses of \f(CW$self\fR..SH "USING RELATIONSHIP WITH SDBM".IX Header "USING RELATIONSHIP WITH SDBM"This example demonstrates an interface for the \s-1SDBM\s0 class. This creates a\&\*(L"using\*(R" relationship between the \s-1SDBM\s0 class and the new class Mydbm..PP.Vb 1\& package Mydbm;\&\& require SDBM_File;\& require Tie::Hash;\& @ISA = qw( Tie::Hash );\&\& sub TIEHASH {\& my $type = shift;\& my $ref = SDBM_File\->new(@_);\& bless {\*(Aqdbm\*(Aq => $ref}, $type;\& }\& sub FETCH {\& my $self = shift;\& my $ref = $self\->{\*(Aqdbm\*(Aq};\& $ref\->FETCH(@_);\& }\& sub STORE {\& my $self = shift;\& if (defined $_[0]){\& my $ref = $self\->{\*(Aqdbm\*(Aq};\& $ref\->STORE(@_);\& } else {\& die "Cannot STORE an undefined key in Mydbm\en";\& }\& }\&\& package main;\& use Fcntl qw( O_RDWR O_CREAT );\&\& tie %foo, "Mydbm", "Sdbm", O_RDWR|O_CREAT, 0640;\& $foo{\*(Aqbar\*(Aq} = 123;\& print "foo\-bar = $foo{\*(Aqbar\*(Aq}\en";\&\& tie %bar, "Mydbm", "Sdbm2", O_RDWR|O_CREAT, 0640;\& $bar{\*(AqCathy\*(Aq} = 456;\& print "bar\-Cathy = $bar{\*(AqCathy\*(Aq}\en";.Ve.SH "THINKING OF CODE REUSE".IX Header "THINKING OF CODE REUSE"One strength of Object-Oriented languages is the ease with which old codecan use new code. The following examples will demonstrate first how one canhinder code reuse and then how one can promote code reuse..PPThis first example illustrates a class which uses a fully-qualified methodcall to access the \*(L"private\*(R" method \s-1\fIBAZ\s0()\fR. The second example will showthat it is impossible to override the \s-1\fIBAZ\s0()\fR method..PP.Vb 1\& package FOO;\&\& sub new {\& my $type = shift;\& bless {}, $type;\& }\& sub bar {\& my $self = shift;\& $self\->FOO::private::BAZ;\& }\&\& package FOO::private;\&\& sub BAZ {\& print "in BAZ\en";\& }\&\& package main;\&\& $a = FOO\->new;\& $a\->bar;.Ve.PPNow we try to override the \s-1\fIBAZ\s0()\fR method. We would like \fIFOO::bar()\fR to call\&\s-1\fIGOOP::BAZ\s0()\fR, but this cannot happen because \fIFOO::bar()\fR explicitly calls\&\fIFOO::private::BAZ()\fR..PP.Vb 1\& package FOO;\&\& sub new {\& my $type = shift;\& bless {}, $type;\& }\& sub bar {\& my $self = shift;\& $self\->FOO::private::BAZ;\& }\&\& package FOO::private;\&\& sub BAZ {\& print "in BAZ\en";\& }\&\& package GOOP;\& @ISA = qw( FOO );\& sub new {\& my $type = shift;\& bless {}, $type;\& }\&\& sub BAZ {\& print "in GOOP::BAZ\en";\& }\&\& package main;\&\& $a = GOOP\->new;\& $a\->bar;.Ve.PPTo create reusable code we must modify class \s-1FOO\s0, flattening classFOO::private. The next example shows a reusable class \s-1FOO\s0 which allows themethod \s-1\fIGOOP::BAZ\s0()\fR to be used in place of \s-1\fIFOO::BAZ\s0()\fR..PP.Vb 1\& package FOO;\&\& sub new {\& my $type = shift;\& bless {}, $type;\& }\& sub bar {\& my $self = shift;\& $self\->BAZ;\& }\&\& sub BAZ {\& print "in BAZ\en";\& }\&\& package GOOP;\& @ISA = qw( FOO );\&\& sub new {\& my $type = shift;\& bless {}, $type;\& }\& sub BAZ {\& print "in GOOP::BAZ\en";\& }\&\& package main;\&\& $a = GOOP\->new;\& $a\->bar;.Ve.SH "CLASS CONTEXT AND THE OBJECT".IX Header "CLASS CONTEXT AND THE OBJECT"Use the object to solve package and class context problems. Everything amethod needs should be available via the object or should be passed as aparameter to the method..PPA class will sometimes have static or global data to be used by themethods. A subclass may want to override that data and replace it with newdata. When this happens the superclass may not know how to find the newcopy of the data..PPThis problem can be solved by using the object to define the context of themethod. Let the method look in the object for a reference to the data. Thealternative is to force the method to go hunting for the data (\*(L"Is it in myclass, or in a subclass? Which subclass?\*(R"), and this can be inconvenientand will lead to hackery. It is better just to let the object tell themethod where that data is located..PP.Vb 1\& package Bar;\&\& %fizzle = ( \*(AqPassword\*(Aq => \*(AqXYZZY\*(Aq );\&\& sub new {\& my $type = shift;\& my $self = {};\& $self\->{\*(Aqfizzle\*(Aq} = \e%fizzle;\& bless $self, $type;\& }\&\& sub enter {\& my $self = shift;\&\& # Don\*(Aqt try to guess if we should use %Bar::fizzle\& # or %Foo::fizzle. The object already knows which\& # we should use, so just ask it.\& #\& my $fizzle = $self\->{\*(Aqfizzle\*(Aq};\&\& print "The word is ", $fizzle\->{\*(AqPassword\*(Aq}, "\en";\& }\&\& package Foo;\& @ISA = qw( Bar );\&\& %fizzle = ( \*(AqPassword\*(Aq => \*(AqRumple\*(Aq );\&\& sub new {\& my $type = shift;\& my $self = Bar\->new;\& $self\->{\*(Aqfizzle\*(Aq} = \e%fizzle;\& bless $self, $type;\& }\&\& package main;\&\& $a = Bar\->new;\& $b = Foo\->new;\& $a\->enter;\& $b\->enter;.Ve.SH "INHERITING A CONSTRUCTOR".IX Header "INHERITING A CONSTRUCTOR"An inheritable constructor should use the second form of \fIbless()\fR which allowsblessing directly into a specified class. Notice in this example that theobject will be a \s-1BAR\s0 not a \s-1FOO\s0, even though the constructor is in class \s-1FOO\s0..PP.Vb 1\& package FOO;\&\& sub new {\& my $type = shift;\& my $self = {};\& bless $self, $type;\& }\&\& sub baz {\& print "in FOO::baz()\en";\& }\&\& package BAR;\& @ISA = qw(FOO);\&\& sub baz {\& print "in BAR::baz()\en";\& }\&\& package main;\&\& $a = BAR\->new;\& $a\->baz;.Ve.SH "DELEGATION".IX Header "DELEGATION"Some classes, such as SDBM_File, cannot be effectively subclassed becausethey create foreign objects. Such a class can be extended with some sort ofaggregation technique such as the \*(L"using\*(R" relationship mentioned earlier orby delegation..PPThe following example demonstrates delegation using an \s-1\fIAUTOLOAD\s0()\fR function toperform message-forwarding. This will allow the Mydbm object to behaveexactly like an SDBM_File object. The Mydbm class could now extend thebehavior by adding custom \s-1\fIFETCH\s0()\fR and \s-1\fISTORE\s0()\fR methods, if this is desired..PP.Vb 1\& package Mydbm;\&\& require SDBM_File;\& require Tie::Hash;\& @ISA = qw(Tie::Hash);\&\& sub TIEHASH {\& my $type = shift;\& my $ref = SDBM_File\->new(@_);\& bless {\*(Aqdelegate\*(Aq => $ref};\& }\&\& sub AUTOLOAD {\& my $self = shift;\&\& # The Perl interpreter places the name of the\& # message in a variable called $AUTOLOAD.\&\& # DESTROY messages should never be propagated.\& return if $AUTOLOAD =~ /::DESTROY$/;\&\& # Remove the package name.\& $AUTOLOAD =~ s/^Mydbm:://;\&\& # Pass the message to the delegate.\& $self\->{\*(Aqdelegate\*(Aq}\->$AUTOLOAD(@_);\& }\&\& package main;\& use Fcntl qw( O_RDWR O_CREAT );\&\& tie %foo, "Mydbm", "adbm", O_RDWR|O_CREAT, 0640;\& $foo{\*(Aqbar\*(Aq} = 123;\& print "foo\-bar = $foo{\*(Aqbar\*(Aq}\en";.Ve.SH "SEE ALSO".IX Header "SEE ALSO"perlboot, perltoot, perltooc.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -