Как мне создать класс Perl? - PullRequest
18 голосов
/ 24 июня 2009

Я пишу классы Perl для удаления избыточности из сценариев, и поскольку в Perl есть много способов создания классов, у меня возникают проблемы с созданием классов должным образом. Так есть ли у кого-нибудь лучший пример занятий?

Самый большой вопрос, который у меня возникает, - если в модуле не должно быть глобальных переменных, как вы используете переменные в sub () в модуле? Как Java self-> foo = 10;

По сути, просто дайте мне класс, написанный на Java или C # или даже C ++, и напишите то же самое на Perl. Также дополнительные пункты для того, чтобы показать, как правильно делать закрытые, защищенные и общедоступные переменные класса. Наследование и интерфейсы были бы полезны, я думаю.

Ответы [ 4 ]

28 голосов
/ 24 июня 2009

типичный способ создания объектов Perl - «благословить» хэш-ссылку. Затем экземпляр объекта может хранить данные в своем собственном наборе хеш-ключей.

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();

В качестве альтернативы, методы доступа / мутатора могут быть добавлены (см. Class :: Accessor, Class :: Accessor :: Chained и т. Д. Для их легкой установки) - это облегчает проверку данных и добавление инкапсуляции (это не применяется) в Perl вы должны убедиться, что ваш код не обходит соответствующий аксессор / мутатор и не обращается напрямую к данным в благословенном хэш-адресе).

24 голосов
/ 24 июня 2009

Ну, 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";

Вот тот же класс, написанный с использованием новых объектов стиля 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";

И 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";

Небольшое примечание: эти два класса - первые два класса лося, которые я когда-либо писал. А вот немного ржавый код 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;
}
17 голосов
/ 24 июня 2009

Check Moose , который является расширением объектной системы Perl 5.

Следующее поможет вам в изучении лося:

4 голосов
/ 24 июня 2009

Кроме лося, о котором люди уже упоминали ...

Если вы просто говорите о классах (то есть, не об объектах), вы обычно создаете данные классов с лексическими переменными в области видимости файла и используете один класс на файл. Вы создаете методы доступа к ним. Есть разные способы справиться с этим.

Однако, похоже, вам нужно начать с чего-то вроде Промежуточный Perl или Дамиана Конвея Object Oriented Perl . Слишком много объяснений, чтобы кто-то нашел время, чтобы воспроизвести все это в ответе Stackoverflow.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...