gpt4 book ai didi

perl - 如何使用插件编写 Perl 对象?

转载 作者:行者123 更新时间:2023-12-04 16:41:37 24 4
gpt4 key购买 nike

如何使用可扩展代码编写 Perl 对象?我在想驱动程序或一些配置,用户可以在其中传递字符串“Classname::Class”或其他东西。谢谢。

例如,对于图类:

my $spg = Graph::ShortestPathGraph->new;
$spg->Algorithm( "Graph::DFS" );
$spg->solve;

$spg->Algorithm( "Graph::BFS" );
$spg->solve;

最佳答案

How do I write extensible code?



有计划。假设您正在编写一个算法来绘制一个
点集。你需要这些点的来源,一个绘图的地方
它们,以及一种用于插入不在其中的点的算法
放。

(只是一个说明,假设“图形”在这里的意思是“图表”,而不是
离散数学意义上的图形。)

让我们定义代表这些操作的角色。一个来源
积分必须能够为我们提供积分:
 package Graphomatic::PointSource;
use Moose::Role;

requires 'get_points'; # return a list of points

1;

绘图仪必须允许我们绘制一个点:
 package Graphomatic::Plot;
use Moose::Role;

requires 'plot_point'; # plot a point
requires 'show_graph'; # show the final graph

1;

当给定两个附近的点时,插值器必须给我们一个点:
 package Graphomatic::Interpolate;
use Moose::Role;

requires 'interpolate_point';

1;

现在,我们只需要根据这些来编写我们的主要应用程序
角色:
 package Graphomatic;
use Moose;

use Graphomatic::PointSource;
use Graphomatic::Plot;
use Graphomatic::Interpolate;

has 'source' => (
is => 'ro',
does => 'Graphomatic::PointSource',
handles => 'Graphomatic::PointSource',
required => 1,
);

has 'plot' => (
is => 'ro',
does => 'Graphomatic::Plot',
handles => 'Graphomatic::Plot',
required => 1,
);

has 'interpolate' => (
is => 'ro',
does => 'Graphomatic::Interpolate',
handles => 'Graphomatic::Interpolate',
required => 1,
);

sub run { # actually render and display the graph
my $self = shift;

my @points = $self->get_points; # delegated from the PointSource
for my $x (some minimum .. some maximum) {
my ($a, $b) = nearest_points( $x, @points );
$self->plot_point( $self->interpolate_point($a, $b, $x) );
}

$self->show_graph;
}

1;

现在定义一些源实现是一件简单的事情。
让我们从文件中读取点:
package Graphomatic::PointSource::File;

use Moose;
use MooseX::FileAttribute;

# ensure, at compile-time, that this class is a valid point
# source
with 'Graphomatic::PointSource';

has_file 'dataset' => ( must_exist => 1, required => 1 );

sub get_points {
my $self = shift;

return parse $self->dataset->slurp;
}

1;

并绘制到 Z 窗口系统:
package Graphomatic::Plot::Z;
use Moose;
use Z;

with 'Graphomatic::Plot';

has 'window' => ( is => 'ro', isa => 'Z::Window', lazy_build => 1);

sub _build_window { return Z->new_window }

sub plot_point {
my ($self, $point) = @_;

$self->window->plot_me_a_point_kthx($point->x, $point->y);
}

sub show_plot {
my $self = shift;
$self->window->show;
}

1;

并使用随机数生成器进行插值(嘿,我很懒,而且我很
不打算查找双三次插值:P):
package Graphomatic::Interpolate::Random;
use Moose;

with 'Graphomatic::Interpolate';

sub interpolate_point {
my ($self, $a, $b, $x) = @_;
return 4; # chosen by fair dice roll.
# guaranteed to be random.
}

1;

现在我们可以将所有部分组装成一个工作程序:
use Graphomatic::PointSource::File;
use Graphomatic::Plot::Z;
use Graphomatic::Interpolate::Random;

my $graphomatic = Graphomatic->new(
source => Graphomatic::PointSource::File->new(
file => 'data.dat',
),
plot => Graphomatic::Plot::Z->new,
interpolate => Graphomatic::Interpolate::Random->new,
);

$graphomatic->run;

现在您可以干净地自定义任何部件而不会影响
其他部分,只需实现“执行”所需的新类
角色。 (如果他们说'with ...'并且他们不符合要求,
加载类后,您将立即收到错误消息。如果你尝试
使用一个实例作为参数,它没有“做”正确的角色,
构造函数会死。

类型安全,这是一件很棒的事情。)

至于处理配置文件,只需以某种方式读取名称和参数,
进而:
my $interpolate_class = get_config('interpolate_class');
Class::MOP::load_class($interpolate_class);
my $interpolate = $interpolate_class->new( %interpolate_class_args );

my $graphomatic = Graphomatic->new( interpolate => $interpolate, ... );

MooseX::YAML是自动化此操作的好方法。

关于perl - 如何使用插件编写 Perl 对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2478009/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com