如何与具有哈希属性的Perl对象进行交互?

bry*_*esk 4 perl hash object

我有一个包含多个变量的类,其中一个是散列(_runs):

sub new
{
    my ($class, $name) = @_;
    my $self = {
        _name => $name,
        ...
        _runs => (),
        _times => [],
        ...
    };
    bless ($self, $class);
    return $self;
}
Run Code Online (Sandbox Code Playgroud)

现在,我要做的就是创建一个访问器/ mutator,以及另一个将新数据推入哈希的子例程.但我有一段时间让所有引用/解除引用/ $ self调用一起工作.我用"不能使用字符串("blah")作为HASH ref等等"烧毁我的眼睛"错误.

对于访问者来说,返回哈希的"最佳实践"是什么?我应该使用以下哪个选项(如果有的话)?:

return $self->{_runs};
return %{ $self->{_runs} };
return \$self->{_runs};
Run Code Online (Sandbox Code Playgroud)

此外,当我在类中的其他子例程中使用哈希时,我使用什么语法来复制它?

my @runs = $self->{_runs};
my @runs = %{ $self->{_runs} };
my @runs = $%{ $self->{_runs} };
my @runs = $$self->{_runs};
Run Code Online (Sandbox Code Playgroud)

迭代键是一样的:

foreach my $dt (keys $self->{_runs})
foreach my $dt (keys %{ $self->{_runs} })
Run Code Online (Sandbox Code Playgroud)

那么实际添加数据呢?

$self->{_runs}{$dt} = $duration;
%{ $self->{_runs} }{$dt} = $duration;
$$self->{_runs}{$dt} = $duration;
Run Code Online (Sandbox Code Playgroud)

你明白了.我一直在阅读有关使用类和有关引用和解除引用的文章的文章,但我似乎无法让我的大脑结合知识并同时使用它们.我最终得到了我的_times数组,但是模仿我的数组语法到哈希没有用.

Iva*_*uev 6

您正在对象中存储对数组或哈希的引用.要将它们与标准函数一起使用,您需要取消引用它们.例如:

@{ $self->{_array_ref_key} }; 
%{ $self->{_hash_ref_key} };
Run Code Online (Sandbox Code Playgroud)

如果需要将参数传递给标准函数:

push( @{ $self->{_array_ref_key} }, $some_value );
for my $hash_key ( keys %{ $self->{_hash_ref_key} }) {
    $self->{_hash_ref_key}{$hash_key}; ## you can access hash value by reference
}
Run Code Online (Sandbox Code Playgroud)

此外$self->{_hash_ref_key}{$hash_key}语法快捷方式$self->{_hash_ref_key}->{$hash_key}(这可以使意义,如果你看到它第一次).

另请查看相应的手册页.


dax*_*xim 5

不妨接受我的评论,并从中做出正确的答案.我将准确说明您的示例代码失败的原因.

use warnings;
my $self = {
    _name => $name,
    _runs => (),
    _times => [],
};
bless ($self, $class);

use Data::Dump::Streamer; DumpLex $self;

__END__
Odd number of elements in anonymous hash at …

$self = bless( {
    _name             => undef,
    _runs             => '_times',
    "ARRAY(0x88dcb8)" => undef,
}, '…' );
Run Code Online (Sandbox Code Playgroud)

列表中的所有元素形成将要bless编辑引用的哈希的键/值对.()是一个空列表,所以你真正表达的是列表'_name', $name, '_runs', '_times', [].您可以看到_times向上移动成为值,并且引用[]被字符串化为散列键.你得到了警告,因为它没有任何价值; 这将被自动强制执行undef.(始终始终启用该warnings编译指示.)

现在对于guts部分:哈希值必须是标量值.数组和散列不是; 但是对它们的引用是.从而:

my $self = {
    _name => $name,
    _runs => {},
    _times => [],
};
Run Code Online (Sandbox Code Playgroud)