Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 使用n-gleton模式表示(和导出)n个独特的事物?_Perl_Singleton - Fatal编程技术网

Perl 使用n-gleton模式表示(和导出)n个独特的事物?

Perl 使用n-gleton模式表示(和导出)n个独特的事物?,perl,singleton,Perl,Singleton,在一组用于模拟国际象棋情况的小类中,我想构建一个表示位置的类。但我只想创建(并导出)有效的64个位置,并在此之后将构造函数设为私有,以防止系统为同一位置创建多个对象。基本上是一个单体,但1=64。64吨重。有点 可能的用法: use Positions; # exports positions my $pos = e4; # something happens... do_foo() if $pos == d5; do_bar() if $pos->row == 8; package

在一组用于模拟国际象棋情况的小类中,我想构建一个表示位置的类。但我只想创建(并导出)有效的64个位置,并在此之后将构造函数设为私有,以防止系统为同一位置创建多个对象。基本上是一个单体,但1=64。64吨重。有点

可能的用法

use Positions; # exports positions

my $pos = e4;

# something happens...
do_foo() if $pos == d5;
do_bar() if $pos->row == 8;
package Position;
use Moo;

has column  => (is => 'ro');
has row     => (is => 'ro');
has name    => (is => 'lazy');

sub _build_name {
    my $self = shift;
    return $self->column . $self->row;
}

sub to_string { shift->name }

# ...
我的解决方案按照我想要的方式工作,但感觉有点不雅观,设计过度

基础知识

use Positions; # exports positions

my $pos = e4;

# something happens...
do_foo() if $pos == d5;
do_bar() if $pos->row == 8;
package Position;
use Moo;

has column  => (is => 'ro');
has row     => (is => 'ro');
has name    => (is => 'lazy');

sub _build_name {
    my $self = shift;
    return $self->column . $self->row;
}

sub to_string { shift->name }

# ...
使用
isa
不会对有效列或行进行错误检查,因为我根本不希望类用户实例化位置对象。现在转到导出:

# prepare 64 positions
my %position;
foreach my $col ('a' .. 'h') {
    foreach my $row (1 .. 8) {

        # build
        my $name    = "$col$row";
        my $pos     = Cherl::Position->new(column => $col, row => $row);

        # remember
        $position{$name} = $pos;
    }
}

# export
sub import {
    my $class   = shift;
    my $caller  = caller;

    # magic!
    no strict 'refs';
    for my $name (sort keys %position) {
        *{$caller . '::' . $name} = sub { $position{$name} };
    }
}

# make it private
sub BUILDARGS {
    my ($class, @args) = @_;
    die 'private' unless +(caller 1)[0] eq __PACKAGE__;
    return $class->SUPER::BUILDARGS(@args);
}
我能想到的替代方案

将为
s和
s添加错误检查,如果两个位置的名称相等,则重载
=
运算符以返回true以正确比较位置。在这个场景中,我有点害怕为同一位置构建大量对象,但这可能是早期优化


所以问题是,是否有更好的方法来设计这个类(使用)。蒂亚!:)

我可能会有一个Create()方法(而不是新的X…),其中包含Create()中的代码,因此它只会创建合法的位置。如果再次尝试在该位置上调用Create(),甚至可以使其返回该位置的当前位置对象


此外,如果担心意外地直接创建位置对象,甚至可能会将实际位置类设为Create()ing类的隐藏子类。

可能是我的Java编程夏季导致我设计过于复杂:/谢谢!:)我喜欢
创建
的想法。