如何创建Perl类?

kth*_*ore 19 oop perl

我正在编写Perl类来从脚本中删除冗余,因为Perl有很多方法可以创建类,所以我在编写类时遇到了麻烦.那么有没有人有一个类的最佳实践示例?

我遇到的最大问题是,如果模块中不存在全局变量,那么如何在模块中的sub()中使用变量?像Java self-> foo = 10;

基本上只是给我一个用Java或C#甚至C++编写的类,并在Perl中编写相同的类.还有一些额外的要点,用于说明如何正确地执行私有,受保护和公共类变量.我想,继承和接口会有所帮助.

plu*_*lus 29

创建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};
}
Run Code Online (Sandbox Code Playgroud)

和用法:

my $obj = SampleObject->new( sample_data => 'hello world',
                             more_data   => 'blah blah blah' );
$obj->sample_method();
Run Code Online (Sandbox Code Playgroud)

或者,可以添加accessor/mutator方法(参见Class :: Accessor,Class :: Accessor :: Chained等,以便于设置这些) - 这使得更容易验证数据并添加封装(它不是在Perl中强制执行的,你必须确保你的代码没有绕过适当的访问者/ mutator并直接访问blessed hashref中的数据.


Cha*_*ens 25

好吧,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";
Run Code Online (Sandbox Code Playgroud)

这是使用新的Moose样式对象编写的同一个类:

#!/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";
Run Code Online (Sandbox Code Playgroud)

并且MooseX :: Declare消除了对更多代码的需求并使事情变得美观:

#!/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";
Run Code Online (Sandbox Code Playgroud)

快速说明,这两个类是我写过的前两个Moose类.这里有一些非常生锈的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;
}
Run Code Online (Sandbox Code Playgroud)


Ala*_*avi 17

查看Moose,它是Perl 5对象系统的扩展.

以下内容将帮助您学习Moose:

  • @mpeters因为链接过时而死亡.如果该链接因任何原因而死亡,这个答案几乎一文不值.这是在StackOverflow FAQ中. (4认同)
  • 你是对的,相反,他给你链接,告诉你如何做到这一点.当链接更好时,为什么要浪费字节从其他地方复制/粘贴. (2认同)