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

Perl5 OOP學(xué)習(xí)筆記

 更新時間: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ù)名。同理,如果有一個foo成員函數(shù)的話,也可以foo MyClass(args),它實(shí)際上是MyClass::foo(MyClass, args);

  話說回來,如果需要初始化對象數(shù)據(jù)又該如何呢?前面說過,對象數(shù)據(jù)保存在引用的數(shù)據(jù)自身,所以我們通常是把一個Hash引用bless成對象。所以我們經(jīng)常會看到這樣調(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)榍罢邆魅氲氖且粋€Hash實(shí)體,而后者傳入的是一個Hash引用。為了兼容這兩種情況,new函數(shù)通常會像下面程序中的寫法:
復(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' );

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

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

  如果想少寫點(diǎn)花括號,可以通過定義setter/getter的辦法來解決。因?yàn)間etter和setter可以根據(jù)有沒參數(shù)來區(qū)分,所以合并在一個函數(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的確可以使程序看起來簡潔不少。但是對對象中的每個數(shù)據(jù)寫一個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寫起來很累人的。如果你只需要一個數(shù)據(jù)對象,網(wǎng)上有個Hash::AsObject的類很好用,用法和上面的最后一個示例差不多。
繼承
  我的確是對繼承這個方面沒怎么研究。不過簡單的繼承大概就是用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)文章

最新評論

青川县| 南宫市| 横峰县| 阳谷县| 原平市| 巢湖市| 柏乡县| 乌恰县| 武安市| 房产| 黑河市| 贞丰县| 富源县| 汽车| 高清| 波密县| 龙州县| 卢氏县| 廉江市| 阳信县| 银川市| 沙河市| 沙洋县| 洞头县| 舒兰市| 绥芬河市| 蒙阴县| 棋牌| 宣恩县| 宣城市| 同心县| 锡林浩特市| 昆明市| 清流县| 河南省| 汶川县| 平阳县| 湘阴县| 吴川市| 绿春县| 山西省|