我正在努力解决数组和标量之间的差异。
我从Config::IniFiles
初始化一个对象。其中一个对象属性是数组。在init方法中,我可以打印数组值和数组大小。
[project]
junk = Perl
junk = is
junk = complicated
从init方法调用内部构造函数
my $ini = Config::IniFiles->new( -file => "config.ini", -default => 'Default' );
my $junk = $ini->val( 'project', 'junk' );
my @junk = split( /\n/, $junk );
say scalar @junk;
foreach ( @junk ) {
say $_;
}
$self->{_junk} = @junk;
3
Perl
is
complicated
现在,我实现了getter方法:
sub getJunkPatterns {
my ($self) = @_;
return $self->{_junk};
}
并像这样称呼它
my @patterns = $self->getJunkPatterns();
say scalar @patterns;
say @patterns;
结果不是我的预期
3
3
对于标量(非数组)属性,这可以正常工作。有谁能告诉我我的阵列出错了什么?有没有人知道如何正确地从Config::IniFiles
获取数组而不需要拆分它们?
答案 0 :(得分:4)
您正在混合数组和数组引用。
您的行$self->{_junk} = ['Test1', 'test2']
将_junk
键的值设置为数组引用。你可以用方括号[]
来判断它。
要使数组脱离引用,您需要取消引用它。你可以在你的吸气器中这样做:
return @{ $self->{_junk} };
或者您将接口定义为数组引用,并让用户解析它。
my @patterns = @{ $self->getJunkPatterns() };
当然,首先需要在该键内部有一个数组引用。无法将数组放入任何内容中。在Perl中,具有多个级别的数据结构必须是。
因此,无论您在何处设置它,都需要看起来像这样:
sub setJunkPatterns {
my ($self, @patterns) = @_;
$self->{_junk} = \@patterns;
}
有关详细信息,请参阅perlref和perlreftut。
您在整个代码中使用$self
,但似乎您不在课堂内。 Perl中的$self
与其他语言中的this
类似。它是对您正在使用的类的实例化对象的引用,该类的在中。因此,当您实例化某个类在之外的对象时,您永远不会调用$self
。
答案 1 :(得分:3)
我认为$ini->val(...)
的代码部分在类中是,并且写入数据的_junk
旨在成为数组引用,唯一有意义的选择。
首先,您可以val
@values = $cfg->val('Section', 'Parameter');
将{em> 作为列表或作为字符串返回
如果要将多行/值字段作为数组返回,只需将数组指定为接收器:
$self->{_junk} = @junk;
因此,不是分配给标量而是分成行,只需分配给数组。
下一步,作业@junk
很可能是错误的,如下所示。
数组_junk
被分配给标量,哈希值唯一可以。这意味着该操作位于标量上下文中,在这种情况下,分配的是数组元素的数量。因此,在该行[@junk]
之后有一个数字而不是一个arrayref,如ouput中所示。见Config::IniFiles。
因此,如果周围的代码允许,请指定一个arrayref,\@junk
(或更高效val
。)
最后,在您的getter中,您可以选择将这些行作为列表或作为该列表的引用返回,如context in perldata所示。
但您也可以考虑像sub getJunkPatterns {
my ($self) = @_;
return (wantarray)
? @{$self->{_junk}};
: join "\n", @{$self->{_junk}};
}
那样将其作为字符串或列表返回,具体取决于调用该方法的answer by simbabque。为此,请使用context检查上下文。如果在列表上下文中调用该方法,则返回一个列表,而在标量上下文中,我们返回一个标量。
val
元素由标量返回的换行符连接,以模仿: $self->{_junk};
的作用。如果您更愿意返回引用更改,则标量返回my @patterns = $object->getJunkPatterns();
。
然后您可以将其用作
my $pattern_string = $object->getJunkPatterns();
或
printArray(w->childArr,w->numChildren,LEN,printString);
如果您选择在标量上下文中返回对该列表的引用,而不是带有行的字符串,请相应地更改getter,然后返回的标量为arrayref。