2009-06-24 54 views
14

我正在编写Perl类来消除脚本中的冗余,因为Perl有很多方法来创建类,所以我一直无法正确地创建类。那么有没有人有一个类的最佳实践例子?如何创建一个Perl类?

我最大的问题是,如果模块中不应该有全局变量如何使用模块中的sub()变量?像Java一样> foo = 10;

基本上只给我一个用Java或C#甚至C++编写的类,并在Perl中编写。此外还要介绍如何正确执行私有,受保护和公共类变量。继承和接口将有助于我猜。

+1

Perl的面向对象的特点是在最好的欠缺有点...:PI会去看看一个简单的.pm模块,看看他们是如何实现 – 2009-06-24 09:31:26

回答

24

创建的Perl对象的典型方式是 '祝福' 一个hashref。对象实例然后可以将数据存储在自己的一组散列键中。

package SampleObject; 

use strict; 
use warnings; 

sub new { 
    my ($class, %args) = @_; 
    return bless { %args }, $class; 
} 

sub sample_method { 
    my ($self) = @_; 
    print $self->{sample_data}; 
} 

及用量:

my $obj = SampleObject->new(sample_data => 'hello world', 
          more_data => 'blah blah blah'); 
$obj->sample_method(); 

可替换地,可以加入存取/突变的方法(参见::类访问器,类::访问器::链式等易于设置的向上这些) - 这使得验证数据和添加封装变得更加容易(它不是在Perl中强制执行的,您必须确保代码不会绕过适当的访问器/增变器并直接访问受保护的hashref中的数据)。

16

检出Moose,它是Perl 5对象系统的扩展。

下面将帮助您学习麋:

+0

我意识到这是一个受欢迎的答案,但它实际上并没有告诉我怎么让我自己的类与其他OOP语言类似。 – kthakore 2009-06-25 13:18:53

+2

然而,后做点你给它。 – 2009-06-25 15:44:40

+2

你是对的,而不是他给你,告诉你该怎么做链接。当链接好得多时,为什么要从别的地方复制/粘贴字节。 – mpeters 2009-06-25 15:59:28

23

那么,Perl很容易,但我在其他语言生锈,所以我会稍微更新它们。这是一个普通的Perl类:

#!/usr/bin/perl 

package Person; 

use strict; 
use warnings; 
use Carp; 

sub new { 
    my $class = shift; 
    my $self = { @_ }; 
    croak "bad arguments" unless defined $self->{firstname} and defined $self->{lastname}; 
    return bless $self, $class; #this is what makes a reference into an object 
} 

sub name { 
    my $self = shift; 
    return "$self->{firstname} $self->{lastname}"; 
} 

#and here is some code that uses it 
package main; 

my $person = Person->new(firstname => "Chas.", lastname => "Owens"); 
print $person->name, "\n"; 

下面是使用新的驼鹿样式对象写入同一个类:

#!/usr/bin/perl 

package Person; 

use Moose; #does use strict; use warnings; for you 

has firstname => (is => 'rw', isa => 'Str', required => 1); 
has lastname => (is => 'rw', isa => 'Str', required => 1); 

sub name { 
    my $self = shift; 
    return $self->firstname . " " . $self->lastname; 
} 

#and here is some code that uses it 
package main; 

my $person = Person->new(firstname => "Chas.", lastname => "Owens"); 
print $person->name, "\n"; 

而且MooseX ::申报消除了更多的代码需要,使事情看起来不错:

#!/usr/bin/perl 

use MooseX::Declare; 

class Person { 
    has firstname => (is => 'rw', isa => 'Str', required => 1); 
    has lastname => (is => 'rw', isa => 'Str', required => 1); 

    method name { 
      return $self->firstname . " " . $self->lastname; 
    } 
} 

#and here is some code that uses it 
package main; 

my $person = Person->new(firstname => "Chas.", lastname => "Owens"); 
print $person->name, "\n"; 

快速注意,这两个类是我写过的前两个穆斯类。这里是一些非常生疏的C++代码(不削减自己就可以了,或者你需要注射破伤风针):

#include <stdio.h> 
#include <string.h> 

class Person { 
    char* firstname; 
    char* lastname; 

    public: 
    Person(char* first, char* last) { 
     firstname = first; 
     lastname = last; 
    } 

    char* name(void) { 
     int len = strlen(firstname) + strlen(lastname) + 1; 
     char* name = new char[len]; 
     name[0] = '\0'; 
     strcat(name, firstname); 
     strcat(name, " "); 
     strcat(name, lastname); 
     return name; 
    } 
}; 

int main(void) { 
    Person* p = new Person("Chas.", "Owens"); 
    char* name = p->name(); 
    printf("%s\n", name); 
    delete name; 
    delete p; 
    return 0; 
} 
4

此外驼鹿,人们已经提到...

如果你是只是谈论类(所以不是对象)时,通常使用范围为文件的词法变量创建类数据,并为每个文件使用一个类。您创建访问器方法来处理它们。有很多方法可以解决这个问题。

但是,这听起来像你需要从Intermediate Perl或达米安康威的Object Oriented Perl开始。有太多的解释,任何人采取重现了这一切的答案#1的时间。