我正在编写Perl类来删除脚本中的冗余,因为Perl有很多方法可以创建类,所以我一直无法正确地编写类。那么有没有人有一个类的最佳实践示例?
我遇到的最大问题是,如果模块中不存在全局变量,那么如何在模块中的sub()中使用变量?像Java self-> foo = 10;
基本上只给我一个用Java或C#甚至C ++编写的类,并在Perl中编写相同的内容。还有一些额外的要点,用于展示如何正确地执行私有,受保护和公共类变量。我想,继承和接口会有所帮助。
答案 0 :(得分:28)
创建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();
或者,可以添加accessor / mutator方法(参见Class :: Accessor,Class :: Accessor :: Chained等,以便于设置这些方法) - 这样可以更容易地验证数据并添加封装(它不是强制执行的)在Perl中,你必须确保你的代码没有绕过适当的访问器/ mutator并直接访问blessed hashref中的数据。
答案 1 :(得分:24)
好吧,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";
快速说明,这两个类是我写过的前两个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;
}
答案 2 :(得分:17)
答案 3 :(得分:4)
除了穆斯,人们已经提到过......
如果您只是在谈论类(因此,不是对象),通常会创建具有作用于文件的词法变量的类数据,并为每个文件使用一个类。您可以创建访问器方法来处理它们。有多种方法可以解决这个问题。
然而,听起来你需要从Intermediate Perl或Damian Conway的Object Oriented Perl开始。在Stackoverflow的答案中,有太多人无法解释任何人花时间重现所有这些内容。