以下是相关的代码片段。
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;
}
此代码有效,我无法在线找到解释它的内容。 几个问题:
基本上我的思绪充满了f%ck,我不知道发生了什么。还必须声明该程序100%有效。
答案 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中看到包装器代码。