7

我有一个带有返回哈希的方法的类。通常,我会得到这样的结果:

%resp = $myclass->sub($foo);

然后像这样访问返回的哈希的成员:

$resp{key}{subkey};

在二维散列的情况下。

我认为必须有一种方法可以将其组合成一条优雅的线条,如下所示:

$myclass->sub($foo)->{key}{subkey}

这显然没有正确取消引用,因为 Perl 在尝试运行代码时会返回:

不能使用字符串 ("1/8") 作为 HASH ref

在尝试随机取消引用序列时,通过查看Perlmonks 上的“参考快速参考”,我想出了以下内容,Perl 没有抱怨,但也没有返回我正在寻找的内容:

$%{$myclass->sub($foo)}->{key}{subkey}

有人能告诉我魔法解除引用转义序列是什么吗?

4

5 回答 5

9

你试图做的既不优雅也不可取。您以某种方式设法在标量上下文中调用例程(这就是"1/8"对应的)。

返回一个哈希引用。

现在,看看:

#!/usr/bin/perl

package My::Mine;

use strict; use warnings;

sub test {
    my %h = (
        a => { z => 1},
        b => { y => 2},
    );
    return %h;
}

package main;

use strict; use warnings;

my $class = 'My::Mine';

print { $class->test }->{a}{z}, "\n";

那不管用。相反,您必须这样做:

print +{ $class->test }->{a}{z}, "\n";

现在,这很优雅(不是!)请参阅perldoc -f print

长话短说,返回对哈希的引用。

请注意,您正在构建的新匿名哈希不是免费的。从子例程返回散列作为平面列表的成本也不是。

于 2010-02-12T22:03:37.753 回答
6

更改 sub 以返回哈希引用效果最好,但要获得您正在寻找的功能:

{ $myclass->sub($foo) }->{key}{subkey}

这将从返回的列表中创建一个哈希引用sub,然后立即取消引用它

编辑:从您的 sub 返回 hashref 而不是 hash(作为列表)的优势主要是性能之一。在 hashref 的情况下,哈希被创建一次,然后被访问。在列表情况下,哈希被创建,然后转换为列表,然后再次创建,然后被取消引用。对于小散列,这不会花费太多时间,但对于较大的散列,这只是运行时不必要的工作。基本上,如果您打算在某些地方将数据用作列表,而在其他地方用作哈希,则可以将哈希作为列表返回。但是,如果您总是计划将其用作哈希,则返回引用会更清晰、更快。

于 2010-02-12T21:57:54.033 回答
2

我会从 sub 返回一个 HASH 引用。否则(可能)您的哈希会无缘无故地变成 LIST 然后再次变成 HASH:

sub mysub() {
  ...
  return \%myhash;
}

返回引用时涉及的复制较少,因此效率更高。

于 2010-02-12T21:53:29.627 回答
1

只需返回一个 hashref 而不是一个哈希:

$myclass->sub($foo)->{key}->{subkey}

于 2010-02-12T21:51:57.443 回答
0

如果您总是只想获得一个子密钥,请编写一个简短的子例程来为您执行此操作,而忘记打高尔夫球。一个优点是您可以轻松添加一些健全性检查:

 sub get_subkey {
      my( $class, $arg, $key, $subkey ) = @_;

      my $hashref = $class->method( $arg );
      return unless ref $hashref;

      return $hashref->{$key}{$subkey};
      }
于 2010-02-13T19:56:01.777 回答