最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Perl5 OOP學(xué)習(xí)筆記第2/2頁

 更新時(shí)間:2009年04月25日 02:07:46   作者:  
在Perl排名持續(xù)下降的情況下學(xué)Perl,似乎是有點(diǎn)不明智。但是,工作需要,不得不學(xué)啊。再說,Perl現(xiàn)在在測試領(lǐng)域還是用得非常多的。Phython雖然也在測試領(lǐng)域開始活躍起來,不過我始終還是不太喜歡Phython的語法。

復(fù)制代碼 代碼如下:

# test.pl
package MyClass;

sub new {
my $this = {};
bless($this);
}

package main;

my $obj1 = MyClass::new();
my $obj2 = MyClass->new();
my $obj3 = new MyClass();

print(join("\n", ref($obj1), ref($obj2), ref($obj3)));

__END__
MyClass
MyClass
MyClass

注意上面new MyClass()的效果和MyClass->new()效果是一樣的。這里new不是關(guān)鍵字,而是函數(shù)名。同理,如果有一個(gè)foo成員函數(shù)的話,也可以foo MyClass(args),它實(shí)際上是MyClass::foo(MyClass, args);

  話說回來,如果需要初始化對(duì)象數(shù)據(jù)又該如何呢?前面說過,對(duì)象數(shù)據(jù)保存在引用的數(shù)據(jù)自身,所以我們通常是把一個(gè)Hash引用bless成對(duì)象。所以我們經(jīng)常會(huì)看到這樣調(diào)用new:
復(fù)制代碼 代碼如下:

my $obj = MyClass->new('key1' => 'value1', 'key2' => 'value2');

或者
復(fù)制代碼 代碼如下:

my $obj = MyClass->new({'key1' => 'value1', 'key2' => 'value2'});

兩種調(diào)用方式的區(qū)別在于new函數(shù)中的處理不同,因?yàn)榍罢邆魅氲氖且粋€(gè)Hash實(shí)體,而后者傳入的是一個(gè)Hash引用。為了兼容這兩種情況,new函數(shù)通常會(huì)像下面程序中的寫法:
復(fù)制代碼 代碼如下:

# test.pl
package MyClass;

sub new {
my $class = shift();
my $this = ref(@_[0]) ? @_[0] : {@_};
bless($this);
}

package main;
use Data::Dumper;

my $obj1 = MyClass->new('name' => 'James Fancy', 'age' => 30);
my $obj2 = MyClass->new({'name' => 'James Fancy', 'age' => 30});

print(Dumper($obj1));
print(Dumper($obj2));

__END__
$VAR1 = bless( {
'name' => 'James Fancy',
'age' => 30
}, 'MyClass' );
$VAR1 = bless( {
'name' => 'James Fancy',
'age' => 30
}, 'MyClass' );

訪問對(duì)象數(shù)據(jù)
  既然通常是Hash引用被bless成對(duì)象,那就只說這種情況。
  既然是Hash引用,所以訪問數(shù)據(jù)最簡單的辦法就跟訪問Hash引用一樣。比如
復(fù)制代碼 代碼如下:

$obj->{'name'} = "You Name";
my $name = $obj->{'name'};
$obj->{'name'} = "You Name";
my $name = $obj->{'name'};

  如果想少寫點(diǎn)花括號(hào),可以通過定義setter/getter的辦法來解決。因?yàn)間etter和setter可以根據(jù)有沒參數(shù)來區(qū)分,所以合并在一個(gè)函數(shù)中成為可能,比如下面的name函數(shù)
復(fù)制代碼 代碼如下:

# test.pl
package MyClass;
sub new {
my $class = shift();
my $this = ref(@_[0]) ? @_[0] : {@_};
bless($this);
}
sub name {
my $this = shift();
if (@_[0]) {
$this->{'name'} = @_[0];
}
return $this->{'name'};
}
package main;
my $obj = MyClass->new('name' => 'James Fancy');
print($obj->name, "\n");
print($obj->name("New Name"), "\n");
__END__
James Fancy
New Name
# test.pl
package MyClass;
sub new {
my $class = shift();
my $this = ref(@_[0]) ? @_[0] : {@_};
bless($this);
}
sub name {
my $this = shift();
if (@_[0]) {
$this->{'name'} = @_[0];
}
return $this->{'name'};
}
package main;
my $obj = MyClass->new('name' => 'James Fancy');
print($obj->name, "\n");
print($obj->name("New Name"), "\n");
__END__
James Fancy
New Name

  使用setter/getter的確可以使程序看起來簡潔不少。但是對(duì)對(duì)象中的每個(gè)數(shù)據(jù)寫一個(gè)getter/setter,還是很累人的,于是,AUTOLOAD函數(shù)就被抬出來了,看看下面的程序
復(fù)制代碼 代碼如下:

package MyClass;

sub new {
my $class = shift();
my $this = ref(@_[0]) ? @_[0] : {@_};
bless($this, $class);
}

sub AUTOLOAD {
my $this = $_[0];
if (!ref($this)) {
return;
}

my $name = $AUTOLOAD;

if (defined($name)) {
$name =~ s/.*:://;
} else {
return;
}

my $class = ref($this);
if (defined($this->{$name}) || @_) {
no strict 'refs';
*{"${class}::$name"} = sub {
my $this = shift();
$this->{$name} = shift() if (@_);

# make a property in hash reference type to HashObject object.
if (ref($this->{$name}) eq 'HASH') {
bless($this->{$name}, $class);
}

return $this->{$name};
};

goto &$name;
}
}

package main;

my $obj = MyClass->new('name' => 'James Fancy');
$obj->more1({'key', 'value of more1->key'});
print($obj->name, "\n");
print($obj->more1->key, "\n");
print($obj->more2({})->key("value of more2->key"), "\n");

__END__
James Fancy
value of more1->key
value of more2->key

這樣調(diào)用起來是不是方便多了?不過AUTOLOAD寫起來很累人的。如果你只需要一個(gè)數(shù)據(jù)對(duì)象,網(wǎng)上有個(gè)Hash::AsObject的類很好用,用法和上面的最后一個(gè)示例差不多。
繼承
  我的確是對(duì)繼承這個(gè)方面沒怎么研究。不過簡單的繼承大概就是用use base語句引入基類而已,比如
復(fù)制代碼 代碼如下:

package Parent;

sub test1 {
print("Parnet::test1\n");
}

sub test {
print("Parent::test\n");
}

package Sub;
use base Parent;

sub test {
print("Sub::test\n");
}

sub test2 {
$_[0]->Parent::test();
}

package main;

my $obj = bless({}, *Sub);
$obj->test();
$obj->test1();
$obj->test2();

__END__
Sub::test
Parnet::test1
Parent::test


參考資料

東南大學(xué)出版社出版,O'Reilly的《精通Perl(影印版)》,brian d foy著
Perl version 5.10.0 documentation,http://perldoc.perl.org/
Hash::AsObject源碼,來自http://search.cpan.org/~nkuitse/Hash-AsObject-0.11/lib/Hash/AsObject.pm

相關(guān)文章

最新評(píng)論

那坡县| 东阳市| 祁阳县| 吉水县| 临桂县| 贵南县| 西城区| 左贡县| 双流县| 偃师市| 台中市| 萝北县| 天津市| 甘洛县| 兰考县| 郸城县| 梅河口市| 庐江县| 社会| 成都市| 镇赉县| 武穴市| 余庆县| 荥阳市| 雅江县| 历史| 海安县| 平顶山市| 扶风县| 阜新| 镇沅| 朔州市| 康马县| 子长县| 托克逊县| 兴义市| 唐河县| 凉山| 疏附县| 石首市| 天镇县|