如何在perl中返回正确的对象属性?

如何在perl中返回正确的对象属性?,perl,object,hash,Perl,Object,Hash,我创建了一个包,用于返回对象的指定属性(简称代码) 我的perl文件接收从终端解析的输入,但在本例中,变量$vendor是硬编码的,用于测试。我有一个散列中的对象列表,我想根据对象返回正确的属性。某些变量已使用占位符删除 $vendor = "atrena"; my %vendor_hash = ( "atrena" => new vendor_info("Variable_server","Variable_location","Advanced_CDC|CDC dftso|D

我创建了一个包,用于返回对象的指定属性(简称代码)

我的perl文件接收从终端解析的输入,但在本例中,变量$vendor是硬编码的,用于测试。我有一个散列中的对象列表,我想根据对象返回正确的属性。某些变量已使用占位符删除

$vendor = "atrena";

my %vendor_hash = (
    "atrena" => new vendor_info("Variable_server","Variable_location","Advanced_CDC|CDC dftso|DFT|gui|GUI|adv_checker|Lint|spl-view-only|view-only-GUI","adv_checker","database","DB"),

    "ansys" => new vendor_info("Variable","Location","agppi|agppi|ane3fl|ane3fl|ansys|ansys|ensemble_gui|ensemble_gui|hfss_desktop|hfss_desktop|hfss_gui|hfss_gui|hfss_solve|hfss_solve|hfsshpc_pack|hfsshpc_pack|optimetrics|optimetrics|q3d_desktop|q3d_desktop|rdacis|rdacis|struct|struct","ane3fl","database", "db"),

    "coventor" => new vendor_info("var","location","COV_ZsplatViewer|Viewer|COV_VoxelModeler|Voxel-Modeler|MEMSp_Import_Package|Import-Package|MEMSp_Innovator_Plugin|Innovator-Plugin|MEMSp_MATLAB_Simulation|MATLAB-Simulation|MEMSp_Platform|Platform|MTI_AutoBuilder|Auto-Builder|MTI_Catapult|Catapult|MTI_CoventorWare|Coventor-Ware|MTI_Memcap|Memcap|MTI_PreProcessor|PreProcessor","database","db","db")   

);

$vendor_object = $vendor_hash{$vendor};

print Dumper( $vendor_object);

$foodb = $vendor_object -> get_database();
转储程序正在打印正确的信息,但是,当我调用get_database()时,调用的数据库始终是列表中最后一个对象的属性,在本例中是coventor。这同样适用于任何一个子程序getter


如何为正确的对象调用正确的属性?

您将
$vars
作为词法变量,其作用域为包含包的文件。因此,该变量只有一个实例,它将始终包含上次设置的对象的数据

我不确定您是从哪里学会这种方法的,但这根本不是Perl对象的工作方式
$vars
的作用域应限定为仅存在于构造函数中,并且访问器应使用传递给它们的对象作为其第一个参数(传统上称为
$self

还有一点,请使用
Class->new()
而不是您在代码中使用的可能有问题的
new Class
语法。

Dave Cross已经是您的直接问题了

这是一个更为惯用的代码版本示例:

{
    package VendorInfo;
    use Moo;

    for my $attr (qw(
        servers
        locations
        favorite
        default_selection
        database
        DB
    )) {
        has $attr => (
            is       => 'ro',
            required => 1,
        );
    }
}


# main program
use strict;
use warnings;

use Data::Dumper;

my %vendor_hash = (
    "atrena" => VendorInfo->new(
        servers           => "Variable_server",
        locations         => "Variable_location",
        favorite          => "Advanced_CDC|CDC dftso|DFT|gui|GUI|adv_checker|Lint|spl-view-only|view-only-GUI",
        default_selection => "adv_checker",
        database          => "database",
        DB                => "DB",
    ),

    "ansys" => VendorInfo->new(
        servers           => "Variable",
        locations         => "Location",
        favorite          => "agppi|agppi|ane3fl|ane3fl|ansys|ansys|ensemble_gui|ensemble_gui|hfss_desktop|hfss_desktop|hfss_gui|hfss_gui|hfss_solve|hfss_solve|hfsshpc_pack|hfsshpc_pack|optimetrics|optimetrics|q3d_desktop|q3d_desktop|rdacis|rdacis|struct|struct",
        default_selection => "ane3fl",
        database          => "database",
        DB                => "db",
    ),

    "coventor" => VendorInfo->new(
        servers           => "var",
        locations         => "location",
        favorite          => "COV_ZsplatViewer|Viewer|COV_VoxelModeler|Voxel-Modeler|MEMSp_Import_Package|Import-Package|MEMSp_Innovator_Plugin|Innovator-Plugin|MEMSp_MATLAB_Simulation|MATLAB-Simulation|MEMSp_Platform|Platform|MTI_AutoBuilder|Auto-Builder|MTI_Catapult|Catapult|MTI_CoventorWare|Coventor-Ware|MTI_Memcap|Memcap|MTI_PreProcessor|PreProcessor",
        default_selection => "database",
        database          => "db",
        DB                => "db",
    ),
);

my $vendor = "atrena";

my $vendor_object = $vendor_hash{$vendor};

print Dumper($vendor_object);

print "The database is: ", $vendor_object->database, "\n";
值得注意的事项:

  • 我将供应商信息重命名为供应商信息。小写模块名(非正式地)保留给pragmata
  • 我将其用作编写类的助手模块
  • Moo提供了一个
    has
    helper函数来声明属性。它还为我生成了一个构造函数,所以我不必自己编写任何样板文件
  • Moo会自动启用/,所以我也不必这样做
  • 间接对象语法(
    method$object
    method class
    ,在您的例子中是
    new vendor\u info
    )是一个坏主意,因为它的语法含糊不清<代码>类->方法(此处:
    VendorInfo->new
    )更好
  • Moo创建的构造函数以键值对的形式获取其参数,而不是一个长列表(如果sub获取的参数超过3个,这是一个好主意)
  • 我声明的每个属性都会获得一个(只读的(因为我使用了
    'ro'
    )访问器,所以客户端代码可以简单地使用
    $object->database

除了其他人的观点之外,您还需要在
.pm
文件的末尾添加一条真实的陈述

这就是我将如何编写您的应用程序

下午四点 main.pl 输出
我喜欢你展示这一点,并且解释得很好很有用。但是我认为,<代码>对于。。。has对于一个真正的新手来说有点太没有样板了。它没有演示
has
是如何工作的,我认为这可能会非常混乱。您也可以编写
has'servers'=>(is=>'ro',required=>1);具有“位置”=>(is=>“ro”,必需=>1);有'favorite'=>(is=>'ro',required=>1)但我无法忍受所有的复制/粘贴:-(
# Only pragmas should start with lower-case letters
package VendorInfo;

sub new{
    my $class = shift;
    my $vars = {
        _servers => shift,
        _locations => shift,
        _favorite => shift,
        _default_selection => shift,
        _database => shift,
        _DB => shift
    };

    return bless $vars, $class;
}

# Just one example accessor...
sub get_database{
    my $self = shift;
    return $self->{_database};
}
{
    package VendorInfo;
    use Moo;

    for my $attr (qw(
        servers
        locations
        favorite
        default_selection
        database
        DB
    )) {
        has $attr => (
            is       => 'ro',
            required => 1,
        );
    }
}


# main program
use strict;
use warnings;

use Data::Dumper;

my %vendor_hash = (
    "atrena" => VendorInfo->new(
        servers           => "Variable_server",
        locations         => "Variable_location",
        favorite          => "Advanced_CDC|CDC dftso|DFT|gui|GUI|adv_checker|Lint|spl-view-only|view-only-GUI",
        default_selection => "adv_checker",
        database          => "database",
        DB                => "DB",
    ),

    "ansys" => VendorInfo->new(
        servers           => "Variable",
        locations         => "Location",
        favorite          => "agppi|agppi|ane3fl|ane3fl|ansys|ansys|ensemble_gui|ensemble_gui|hfss_desktop|hfss_desktop|hfss_gui|hfss_gui|hfss_solve|hfss_solve|hfsshpc_pack|hfsshpc_pack|optimetrics|optimetrics|q3d_desktop|q3d_desktop|rdacis|rdacis|struct|struct",
        default_selection => "ane3fl",
        database          => "database",
        DB                => "db",
    ),

    "coventor" => VendorInfo->new(
        servers           => "var",
        locations         => "location",
        favorite          => "COV_ZsplatViewer|Viewer|COV_VoxelModeler|Voxel-Modeler|MEMSp_Import_Package|Import-Package|MEMSp_Innovator_Plugin|Innovator-Plugin|MEMSp_MATLAB_Simulation|MATLAB-Simulation|MEMSp_Platform|Platform|MTI_AutoBuilder|Auto-Builder|MTI_Catapult|Catapult|MTI_CoventorWare|Coventor-Ware|MTI_Memcap|Memcap|MTI_PreProcessor|PreProcessor",
        default_selection => "database",
        database          => "db",
        DB                => "db",
    ),
);

my $vendor = "atrena";

my $vendor_object = $vendor_hash{$vendor};

print Dumper($vendor_object);

print "The database is: ", $vendor_object->database, "\n";
package VendorInfo;

use strict;
use warnings 'all';

sub new {
    my $class = shift;

    my $self;

    @{$self}{qw/
        _servers
        _locations
        _favorite
        _default_selection
        _database _DB
    /} = @_;

    return bless $self, $class;
}

sub get_locations {
    my $self = shift;
    return $self->{_locations};
}

sub get_database {
    my $self = shift;
    return $self->{_database};
}

sub get_DB {
    my $self = shift;
    return $self->{_DB};
}

1;
use strict;
use warnings 'all';

use VendorInfo;
use Data::Dumper;

my $vendor = 'atrena';

my %vendor_hash = (
    atrena => VendorInfo->new(
        'Variable_server',
        'Variable_location',
        'Advanced_CDC|CDC dftso|DFT|gui|GUI|adv_checker|Lint|spl-view-only|view-only-GUI',
        'adv_checker',
        'database',
        'DB',
    ),
    ansys => VendorInfo->new(
        'Variable',
        'Location',
        'agppi|agppi|ane3fl|ane3fl|ansys|ansys|ensemble_gui|ensemble_gui|hfss_desktop|hfss_desktop|hfss_gui|hfss_gui|hfss_solve|hfss_solve|hfsshpc_pack|hfsshpc_pack|optimetrics|optimetrics|q3d_desktop|q3d_desktop|rdacis|rdacis|struct|struct',
        'ane3fl',
        'database',
        'db',
    ),
    coventor => VendorInfo->new(
        'var',
        'location',
        'COV_ZsplatViewer|Viewer|COV_VoxelModeler|Voxel-Modeler|MEMSp_Import_Package|Import-Package|MEMSp_Innovator_Plugin|Innovator-Plugin|MEMSp_MATLAB_Simulation|MATLAB-Simulation|MEMSp_Platform|Platform|MTI_AutoBuilder|Auto-Builder|MTI_Catapult|Catapult|MTI_CoventorWare|Coventor-Ware|MTI_Memcap|Memcap|MTI_PreProcessor|PreProcessor',
        'database',
        'db',
        'db',
    ),
);

my $vendor_object = $vendor_hash{$vendor};

print Dumper $vendor_object;

my $foodb = $vendor_object->get_database;

print $foodb, "\n";
$VAR1 = bless( {
                 '_servers' => 'Variable_server',
                 '_default_selection' => 'adv_checker',
                 '_locations' => 'Variable_location',
                 '_database' => 'database',
                 '_DB' => 'DB',
                 '_favorite' => 'Advanced_CDC|CDC dftso|DFT|gui|GUI|adv_checker|Lint|spl-view-only|view-only-GUI'
               }, 'VendorInfo' );
database