Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.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中的2个参数的子例程的一个参数_Perl_Subroutine - Fatal编程技术网

如何解析传递给定义为接受Perl中的2个参数的子例程的一个参数

如何解析传递给定义为接受Perl中的2个参数的子例程的一个参数,perl,subroutine,Perl,Subroutine,我正在创建一个新对象,如下所示: my $new_obj = new P_module({key => 'abc'}); sub new { my ($pkg, $input) = @_; my $obj = {}; bless ($obj, ref($pkg)||$pkg); $obj->{key} = $input->{key}; } p_模块的构造函数定义如下: my $new_obj = new P_module({key =>

我正在创建一个新对象,如下所示:

my $new_obj = new P_module({key => 'abc'});
sub new {
    my ($pkg, $input) = @_;
    my $obj = {};
    bless ($obj, ref($pkg)||$pkg);
    $obj->{key} = $input->{key};
 }
p_模块的构造函数定义如下:

my $new_obj = new P_module({key => 'abc'});
sub new {
    my ($pkg, $input) = @_;
    my $obj = {};
    bless ($obj, ref($pkg)||$pkg);
    $obj->{key} = $input->{key};
 }

从我读到的内容来看,由于散列是作为参数传递给new的,所以它将表示为一个2元素数组。所以,pkg应该是关键,输入应该是abc。那么,obj是如何保存一个key的,而$input->{key}甚至意味着什么呢?

周围的大括号创建了一个散列引用或hashref,它是一个标量。参数值将为

$pkg—包含包的名称,可能是P_模块 $input-对提供的哈希的引用 代码$input->{key}访问与key键相关联的值,该值由调用方提供

my $new_obj = new P_module({key => 'abc'});
这被认为是更好的写作风格

my $new_obj = P_module->new({key => 'abc'});
您可以添加另一个键,如中所示

my $new_obj = P_module->new({key => 'abc', other => 'unused'});
与键关联的值将被复制到对象的状态

$obj->{key} = $input->{key};
请注意,Perl子例程返回最后一个表达式的值,因此您的代码有一个bug。您希望P_module::new的最后一行是

因为这将返回祝福对象,然后该对象可用于调用其他方法,例如


周围的大括号创建一个散列引用或hashref,它是一个标量。参数值将为

$pkg—包含包的名称,可能是P_模块 $input-对提供的哈希的引用 代码$input->{key}访问与key键相关联的值,该值由调用方提供

my $new_obj = new P_module({key => 'abc'});
这被认为是更好的写作风格

my $new_obj = P_module->new({key => 'abc'});
您可以添加另一个键,如中所示

my $new_obj = P_module->new({key => 'abc', other => 'unused'});
与键关联的值将被复制到对象的状态

$obj->{key} = $input->{key};
请注意,Perl子例程返回最后一个表达式的值,因此您的代码有一个bug。您希望P_module::new的最后一行是

因为这将返回祝福对象,然后该对象可用于调用其他方法,例如

首先,

my $new_obj = new P_module({ key => 'abc' });
最好写为

my $new_obj = P_module->new({ key => 'abc' });
sub new {
    my ($class, $input) = @_;
    my $self = { %$input };
    return bless $self, $class;
}
这是

my %anon = ( key => 'abc' );
my $new_obj = P_module->new(\%anon);
进行方法调用时,->的invocant剩余部分作为第一个参数传递。这意味着$pkg是字符串P_模块,$input是{key=>'abc'}返回的引用

由于$input是对散列的引用,$input->{key}从引用的散列中获取具有key key的元素的值

我会怎么写这个:

sub new {
    my ($class, %args) = @_;
    my $self = bless({}, $class);      # If base class.
    #my $self = $class->SUPER::new();  # If inheriting.
    $self->{key} = $args{$key};
    return $self;
 }

 my $obj = P_module->new( key => 'abc' );
调用程序中不需要散列,也没有理由支持$existing_obj->new。它还使用了更多的标准名称$class和$self。

首先

my $new_obj = new P_module({ key => 'abc' });
最好写为

my $new_obj = P_module->new({ key => 'abc' });
sub new {
    my ($class, $input) = @_;
    my $self = { %$input };
    return bless $self, $class;
}
这是

my %anon = ( key => 'abc' );
my $new_obj = P_module->new(\%anon);
进行方法调用时,->的invocant剩余部分作为第一个参数传递。这意味着$pkg是字符串P_模块,$input是{key=>'abc'}返回的引用

由于$input是对散列的引用,$input->{key}从引用的散列中获取具有key key的元素的值

我会怎么写这个:

sub new {
    my ($class, %args) = @_;
    my $self = bless({}, $class);      # If base class.
    #my $self = $class->SUPER::new();  # If inheriting.
    $self->{key} = $args{$key};
    return $self;
 }

 my $obj = P_module->new( key => 'abc' );

调用程序中不需要散列,也没有理由支持$existing_obj->new。它还使用了更多的标准名称$class和$self。

您有这样的理由吗:

bless ($obj, ref($pkg)||$pkg);
而不是这个

bless ($obj, $pkg);
如果不是,那么我假设您从其他代码的某个地方剪切并粘贴了它。你可能想要的是后者

ref$pkg | |$pkg允许您执行以下操作:

my $new_object = $existing_obj->new;
而不是

my $new_object = new Classname;
既然你可能不需要这样做,那就坚持下去吧

bless ($obj, $pkg);

你有这样的理由吗:

bless ($obj, ref($pkg)||$pkg);
而不是这个

bless ($obj, $pkg);
如果不是,那么我假设您从其他代码的某个地方剪切并粘贴了它。你可能想要的是后者

ref$pkg | |$pkg允许您执行以下操作:

my $new_object = $existing_obj->new;
而不是

my $new_object = new Classname;
既然你可能不需要这样做,那就坚持下去吧

bless ($obj, $pkg);

当你调用一个方法时,对象本身在幕后传递;或者,如果sub使用,则它是构造函数,并传递类名。因此,任何方法都将对象或类名作为其第一个参数。其余的是显式传递给方法的参数

传递一个散列引用{…},什么是标量。因此,如果将完全传递的类名分配给$pkg,则将其分配给$input

该接口的构造函数(带有散列引用)通常简单地写为

my $new_obj = P_module->new({ key => 'abc' });
sub new {
    my ($class, $input) = @_;
    my $self = { %$input };
    return bless $self, $class;
}
其中,由于返回了最后一个已计算语句的返回,因此可以省略return。最后两行可以写为return{%$input},$class;,一个匿名hashref被初始化,放入它的包$class中,所以它是一个对象,然后返回

注意,您不必传递hashref;一个简单的散列使得接口更干净。如果可能还有其他参数,则需要使用引用, 使解析所有这些成为可能

但是,您通常希望处理参数。首先,您必须检查它们是否符合您的类支持的内容,而不仅仅是bli ndly将用户传递的密钥分配给属性。然后计算出默认值(如果您提供了它们),检查值(如果您需要),等等

数据的初始化有时被拆分为一个单独的子例程。比如说

sub new {
    my ($class, $input) = @_;
    my $self = {};
    bless $self, $class;       # $self is an object now
    $self->_init($input);      # on which methods can be called
    return $self;
}

sub _init {
    my ($self, $args) = @_;
    # Check arguments, work out defaults (etc), 
    # then assign to self as appropriate
    %$self = %$args;
}
代码通过引用写回,以便更新new中的$self

这应该与正常的方法调用一起使用

my $new_obj = P_module->new({key => 'abc', other => '...'});
不使用间接符号表示新的p_模块。构造器主要是通过自定义调用的new(你可以随意调用它),它是一个普通的子特殊构造器,因为它允许引用通常是散列引用,因此传递的是类名而不是对象。因此,它知道它的包,并且是一个对象

文献:课程是一个软件包、教程和参考资料

一旦您熟悉了Perl内置的面向对象工具(我建议您这么做),就会有许多模块使所有这些变得更加容易


首先推荐的是非常现代且重量轻的方法。

当你调用一个方法时,对象本身在幕后传递;或者,如果sub使用,则它是构造函数,并传递类名。因此,任何方法都将对象或类名作为其第一个参数。其余的是显式传递给方法的参数

传递一个散列引用{…},什么是标量。因此,如果将完全传递的类名分配给$pkg,则将其分配给$input

该接口的构造函数(带有散列引用)通常简单地写为

my $new_obj = P_module->new({ key => 'abc' });
sub new {
    my ($class, $input) = @_;
    my $self = { %$input };
    return bless $self, $class;
}
其中,由于返回了最后一个已计算语句的返回,因此可以省略return。最后两行可以写为return{%$input},$class;,一个匿名hashref被初始化,放入它的包$class中,所以它是一个对象,然后返回

注意,您不必传递hashref;一个简单的散列使得接口更干净。如果可能还有其他参数,则需要使用引用, 使解析所有这些成为可能

但是,您通常希望处理参数。首先,您必须检查它们是否符合类支持的内容,而不是盲目地将用户传递的键分配给属性。然后计算出默认值(如果您提供了它们),检查值(如果您需要),等等

数据的初始化有时被拆分为一个单独的子例程。比如说

sub new {
    my ($class, $input) = @_;
    my $self = {};
    bless $self, $class;       # $self is an object now
    $self->_init($input);      # on which methods can be called
    return $self;
}

sub _init {
    my ($self, $args) = @_;
    # Check arguments, work out defaults (etc), 
    # then assign to self as appropriate
    %$self = %$args;
}
代码通过引用写回,以便更新new中的$self

这应该与正常的方法调用一起使用

my $new_obj = P_module->new({key => 'abc', other => '...'});
不使用间接符号表示新的p_模块。构造器主要是通过自定义调用的new(你可以随意调用它),它是一个普通的子特殊构造器,因为它允许引用通常是散列引用,因此传递的是类名而不是对象。因此,它知道它的包,并且是一个对象

文献:课程是一个软件包、教程和参考资料

一旦您熟悉了Perl内置的面向对象工具(我建议您这么做),就会有许多模块使所有这些变得更加容易


首先推荐的是非常现代且重量较轻的款式。

我同意。在不太可能的情况下,您需要$existing_obj->new,您仍然可以使用ref$existing_obj->new。就我而言,如果需要克隆,这和一个单独的克隆构造函数要干净得多。也就是说,这个答案实际上是一个评论,我会将其标记为评论。如果评论系统允许必要的空间和格式来进行详细解释,我会将其作为评论。我同意。在不太可能的情况下,您需要$existing_obj->new,您仍然可以使用ref$existing_obj->new。就我而言,如果需要克隆,这和一个单独的克隆构造函数要干净得多。也就是说,这个答案实际上是一个注释,我会将其标记为注释。如果注释系统允许使用必要的空间和格式来进行详细解释,我会将其作为注释。my$self=my$self={%$input};返回$self$class;更简单的是写返回{%$input},$class@ikegami我不再展示更简洁的方式,我已经输入了确切的表单,考虑到这个的基本目的。但这很诱人。。。补充。感谢您的编辑。my$self=my$self={%$input};返回$self$class;更简单的是写返回{%$input},$class@ikegami我不再展示更简洁的方式,我已经输入了确切的表单,考虑到这个的基本目的。但这很诱人。。。补充。谢谢你的编辑。非常感谢。这是一个非常有用的解释:非常感谢。这是一个非常有用的解释:我没有考虑。我只是发布了我无法解释的代码。谢谢你指出这个错误,我没有考虑过。我只是发布了我无法解释的代码。谢谢你指点我 不过,这不是错误。