将零参数传递给需要它们的子程序时会发生什么?

时间:2015-03-20 08:06:05

标签: perl

以下是相关的代码片段。

Slic3r :: Print :: Simple的一个属性:

has '_print' => (
is      => 'ro',
default => sub { Slic3r::Print->new },
handles => [qw(apply_config extruders expanded_output_filepath
                total_used_filament total_extruded_volume
                placeholder_parser process)],
);

相关子程序:

sub new {
# TODO: port PlaceholderParser methods to C++, then its own constructor
# can call them and no need for this new() method at all
my ($class) = @_;
my $self = $class->_new;
$self->placeholder_parser->apply_env_variables;
$self->placeholder_parser->update_timestamp;
return $self;
}

此代码有效,我无法在线找到解释它的内容。 几个问题:

  1. $ class分配的值是多少?我猜它被分配了调用Print :: Simple对象,但我还没能用
  2. 进行验证
  3. 我无法找到_new的代码,但是如果$ class是一个Simple对象,那么它应该是Moo :: Object的子类,但是我无法在包中找到相关的子例程。 / LI>
  4. 对placeholder_parser的调用似乎表明$ self引用了一个Simple对象,但是我不知道如何调用该委托。我认为调用委托将从Slic3r :: Print-> new返回的任何内容调用相关方法,但这是在方法返回值之前调用委托。我做了一个搜索,在这个程序的目录或Perl库的任何地方都找不到placeholder_parser子例程的定义。那究竟是做什么的呢?
  5. 基本上我的思绪充满了f%ck,我不知道发生了什么。还必须声明该程序100%有效。

1 个答案:

答案 0 :(得分:5)

首先,这个Slic3r项目违反了基本的Perl约定。运行perl Build.PL应该只配置构建,而是安装依赖项,构建并运行测试。

要实现的第二件事是Slic3r Perl模块是libslic3r C ++库的包装器。 Perl代码可能是调用C ++库中定义的方法而不是Perl代码。要真正了解正在发生的事情,请获取source code

的副本
  

$ class分配了什么值?

方法调用的第一个参数是invocant,即->左侧的东西。对于类方法,它是类的名称。对于对象方法,它就是对象。

例如......

package Some::Class;
sub foo {
    my $class = shift;
    print "$class\n";
}

Some::Class->foo;  # prints 'Some::Class'
  

我找不到_new的代码,但是如果$ class是一个Simple对象,那么它应该是Moo :: Object的子类,但是我找不到包中的相关子例程。

Moo不提供_new方法。

它需要一些跟踪,但接近我可以告诉_new是由C ++包装器代码创建的构造函数。如果您查看xs / buildtmp / XS.c,您会看到类似......

的内容
XS_EUPXS(XS_Slic3r__Print__new)

这是调用Slic3r C ++库并将C ++对象转换为Perl对象的代码。它由Module::Build::WithXSpp自动生成。

  

对placeholder_parser的调用似乎表明$ self引用了一个Simple对象

这可能是正确的。 $self包含$class->_new返回的任何内容,如果表现良好,可能是Slic3r :: Print :: Simple对象。

  

但是我不明白这个代表是如何被调用的。我认为调用委托将调用Slic3r :: Print-> new返回的相关方法,但这是在方法返回值之前调用委托。

Perl中new没有什么神奇之处。它被用作构造函数只是一个约定。在new返回之前,您可以使用完全形成的对象。

这是_new vs new发挥作用的地方。 _new是C ++对象构造函数。它从C ++库中获取基本的Slic3r :: Print对象。 new然后在该对象上调用其他方法。

  

Morever我做了一个搜索,发现没有为此程序的目录或Perl库中的任何位置定义placeholder_parser子例程。那究竟是什么呢?

placeholder_parser是xs / src / libslic3r / Print.cpp中libslic3r C ++库的一个方法。您可以在xs / buildtmp / XS.c中看到包装器代码。