Perl与包一起使用时,不推荐使用散列作为引用

时间:2015-01-28 22:05:23

标签: perl

我有一个名为News(原始名称,我知道)的模块,其中包含一个名为get_fields的方法,此方法返回属于该模块的所有字段,如下所示

sub get_fields {
  my $self = shift;

  return $self;
} 

现在,当我在不同的模块中将其称为这样的时候,我需要在字段中进行操作

my %fields = %{ $news->get_fields };

我发现这样做可以防止这个问题

  

引用键的参数类型必须是非散列的hashref或   数组引用

当我迭代这样的其他字段时

foreach my $key ( keys %fields ) {
  %pairs->{$key} = %fields->{$key} if %fields->{$key};
}

为了使用字段的值,我得到了这个警告

  

不推荐使用散列作为参考

指向foreach循环。

如何在不收到失业警告的情况下避免此错误消息?

1 个答案:

答案 0 :(得分:2)

我认为你在对象哈希之间混淆了。 get_fields将返回$self - 虽然我无法确定,看起来它将会返回一个受祝福的物体。

现在,受祝福的物体与哈希非常相似,但它们并不相同。您可以使用ref函数测试差异。

所以问题更多 - 为什么你这样做?为什么要尝试将对象引用转换为哈希?因为这就是你正在做的事情:

my %fields = %{ $news->get_fields };

因为从根本上说 - 即使这样有效,这将是一件可怕的事情。对象的要点,目的和原因是封装 - 例如事情外部模块不会插入里面的东西

那么为什么不让get_fields返回一个字段列表,然后你可以迭代并进行方法调用?这真的是做这样的事情的“正确”方式。

sub get_fields {
    my ( $self ) = @_;
    return keys %$self; 
}

或者,如果确实必须,则在对象中嵌入一个方法,该方法返回为哈希 - 而不是对象引用 - 然后您可以在外部进行操作。

通常 - 除非你操纵整个哈希值,否则不要引用带有%前缀的哈希值。

要从%pairs中提取单个元素,应该执行:

foreach my $key ( keys %pairs ) { 
    print $pairs{$key},"\n";
}

如果$pairs{$key}的内容是参考,那么您可以使用->表示您应该取消引用,例如$pairs -> {$key}