perl - Perl:如何使用现有包作为新类/对象的基础
问题描述
我有一个 Perl 包,它不是作为 OOP 类编写的。我们称之为 PkgA。PkgA 定义了子程序和变量。
我想在我的主包中实例化它两次,每个实例都有自己的包变量值集。
我认为将 PkgA 变成一个类,并通过构造该类的 2 个对象来实例化它两次将是正确的路径。
为了演示我的问题,我创建了两个文件:PkgA.pm 和 Mail.pl - 它们出现在底部。
PkgA 包含对象变量和局部变量的混合。
对象变量:_CoreName
、_is_uchipsim_test
和OOPVar
。它们代表了我在将 PkgA 转换为对象时添加的那些变量。
局部变量:NonOOPVar
。它代表原始的 PkgA 变量。
程序在 Main 下创建两个 PkgA 实例:main_PkgA 和 aux_PkgA。然后它为 main_PkgA 调用 process_args,然后是 aux_PkgA。
OOPVar
process_args 为和 赋值NonOOPVar
。在 main_PkgA 中,它们将为 {100,101},在 aux_PkgA 中,它们将为 {200,201}。
然后程序在两个实例中调用 load_mem。此子例程仅打印 OOPVar 和 NonOOPVar。您可以在打印到屏幕的输出中看到:
main_PkgA: NonOOPVar = 200, OOPVar = 101
aux_PkgA : NonOOPVar = 200, OOPVar = 201
因此,OOPVar 都具有正确的值,但 main_PkgA 的 NonOOPVar 带有 aux_PkgA 的值!
我需要找到一种方法让 NonOOPVar 知道它所属的实例。
PkgA.pm:
#!/usr/bin/perl
package PkgA;
require 5.000;
push(@ISA,PkgA.pm);
sub new {
print ("Package PkgA::new was called \n");
my $class = shift;
# Receive parameters from the containing module
my $self = {
_CoreName => shift,
_is_uchipsim_test => shift,
OOPVar => None
};
printf("Class = %s, Core name = %s is_uchipsim_test = %d, OOPVar = %d\n",$class,$self->{_CoreName},$self->{_is_uchipsim_test},$self->{OOPVar});
bless $self, $class;
return $self;
};
sub get_core_name {
my ($self) = shift;
return $self->{_CoreName};
}
sub get_is_uchipsim_test {
my ($self) = shift;
return $self->{_is_uchipsim_test};
}
my ($NonOOPVar);
sub process_args {
$this = shift @_;
my (@args) = @_;
$NonOOPVar = @args[0];
$this->{OOPVar} = $NonOOPVar + 1;
printf("this = %s, args size = %d, args[0] = %s, NonOOPVar = %d, OOPVar = %d\n",$this, scalar @args, $args[0],$NonOOPVar,$this->{OOPVar});
};
sub load_mem {
$this = shift @_;
printf("load_mem, this = %s, NonOOPVar = %d, OOPVar = %d \n",$this, $NonOOPVar,$this->{OOPVar});
};
1;
主文件
#!/usr/bin/perl
use PkgA;
$main_PkgA = new PkgA("PkgA_main",1); # Arguments of new(): _CoreName, _is_uchipsim_test,
$aux_PkgA = new PkgA("PkgA_aux" ,2);
$MainCoreName = $main_PkgA->get_core_name();
$AuxCoreName = $aux_PkgA->get_core_name();
printf("Main: Instantiate systest_dot11acphy for MAIN core. Printing its CoreName field: %s\n",$main_PkgA->get_core_name());
printf("Main: Instantiate systest_dot11acphy for AUX core. Printing its CoreName field: %s\n",$aux_PkgA->get_core_name());
$main_PkgA->process_args(100);
$aux_PkgA->process_args(200);
$main_PkgA->load_mem();
$aux_PkgA->load_mem();
解决方案
这有几件事不对劲。首先,使用 strict 和 warnings 将帮助您解决几乎所有的错误。
use strict;
use warnings;
使用它来创建新对象。您的另一种方式是间接对象表示法。这不好
$aux_PkgA = PkgA->new("PkgA_aux" ,2);
使用 $ 获取单个值,使用 @ 获取多个值
sub process_args {
my $this = shift @_;
my (@args) = @_;
$this->{NonOOPVar} = $args[0];
$this->{OOPVar} = $this->{NonOOPVar} + 1;
printf("this = %s, args size = %d, args[0] = %s, NonOOPVar = %d, OOPVar = %d\n",$this, scalar @args, $args[0],$this->{NonOOPVar},$this->{OOPVar});
};
你正在调用一个你不想调用的值。您启动了一个不是对象本地的变量 $NonOOPVar。它在对象之间共享,因为它在主程序范围内。使用 strict 和 warning 可以清楚地说明这是如何发生的,而您将无法做到这一点。
printf("load_mem, this = %s, NonOOPVar = %d, OOPVar = %d \n",$this, $this->{NonOOPVar},$this->{OOPVar});
PkgA.pm
#!/usr/bin/perl
use strict;
use warnings;
package PkgA;
my $NonOOPVar = 200;
sub new {
print ("Package PkgA::new was called \n");
my $class = shift;
# Receive parameters from the containing module
my $self = {
_CoreName => shift,
_is_uchipsim_test => shift,
OOPVar => undef
};
printf("Class = %s, Core name = %s is_uchipsim_test = %d, OOPVar = %d\n",$class,$self->{_CoreName},$self->{_is_uchipsim_test},$self->{OOPVar});
bless $self, $class;
return $self;
};
sub get_core_name {
my ($self) = shift;
return $self->{_CoreName};
}
sub get_is_uchipsim_test {
my ($self) = shift;
return $self->{_is_uchipsim_test};
}
sub process_args {
my $this = shift @_;
my (@args) = @_;
$this->{NonOOPVar} = $args[0];
$this->{OOPVar} = $this->{NonOOPVar} + 1;
printf("this = %s, args size = %d, args[0] = %s, NonOOPVar = %d, OOPVar = %d\n",$this, scalar @args, $args[0],$this->{NonOOPVar},$this->{OOPVar});
};
sub load_mem {
my $this = shift @_;
printf("load_mem, this = %s, NonOOPVar = %d, OOPVar = %d \n",$this, $this->{NonOOPVar},$this->{OOPVar});
#printf("load_mem, this = %s, NonOOPVar = %d, OOPVar = %d \n",$this, $NonOOPVar,$this->{OOPVar});
};
1;
主文件
#!/usr/bin/perl
use strict;
use warnings;
use PkgA;
my $main_PkgA = PkgA->new("PkgA_main",1); # Arguments of new(): _CoreName, _is_uchipsim_test,
my $aux_PkgA = PkgA->new("PkgA_aux" ,2);
my $MainCoreName = $main_PkgA->get_core_name();
my $AuxCoreName = $aux_PkgA->get_core_name();
printf("Main: Instantiate systest_dot11acphy for MAIN core. Printing its CoreName field: %s\n",$main_PkgA->get_core_name());
printf("Main: Instantiate systest_dot11acphy for AUX core. Printing its CoreName field: %s\n",$aux_PkgA->get_core_name());
$main_PkgA->process_args(100);
$aux_PkgA->process_args(200);
$main_PkgA->load_mem();
$aux_PkgA->load_mem();
推荐阅读
- c# - c# - 如何在c#中将进程窗口集中在正在运行的webbrowser窗口上?
- mysql - 如何通过SQL获取prestashop产品属性
- python - scikit learn:5 折交叉验证和训练测试拆分
- c - Winsock 客户端和服务器无法连接
- html - 跨整行 CSS GRID 的水平边框
- mysql - Rails 登录背后的逻辑是什么?
- iis - 尝试使用非英文字符提供静态文件时出现 404
- sql - Sql server 从二进制数据类型到数值数据的转换问题
- shell - shell 脚本中的命令 curl 格式错误
- node.js - 如何使用 Github API 为 github 存储库加注星标 - 我的请求有什么问题?