如何在perl中返回正确的对象属性?
我创建了一个包,用于返回对象的指定属性(简称代码) 我的perl文件接收从终端解析的输入,但在本例中,变量$vendor是硬编码的,用于测试。我有一个散列中的对象列表,我想根据对象返回正确的属性。某些变量已使用占位符删除如何在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
$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提供了一个
helper函数来声明属性。它还为我生成了一个构造函数,所以我不必自己编写任何样板文件has
- 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