perl:打印对象属性

时间:2012-11-05 20:05:41

标签: perl reference

我正在使用Net :: Amazon :: EC2库,并且找不到打印对象属性的简单方法:

这有效:

my $snaps = $ec2->describe_snapshots();
foreach my $snap ( @$snaps ) {
  print $snap->snapshot_id . " " .  $snap->volume_id . "\n";
}

但如果我尝试:

 print "$snap->snapshot_id $snap->volume_id \n";

我得到了

Net::Amazon::EC2::Snapshot=HASH(0x4c1be90)->snapshot_id

是否有一种简单的方法可以在打印内打印属性值?

7 个答案:

答案 0 :(得分:7)

不是你想要的方式。实际上,您使用$snap->snapshot_id所做的就是调用方法(如sub中所述)。 Perl不能在双引号字符串中执行此操作。它会插入变量$snap。这就像HASH(0x1234567),因为它就是这样的:哈希的bless ed引用。

插值仅适用于标量(和数组,但我会省略它)。你可以去:

print "$foo $bar"; # scalar
print "$hash->{key}"; # scalar inside a hashref
print "$hash->{key}->{moreKeys}->[0]"; # scalar in an array ref in a hashref...

有一种方法可以做到:你可以在引用的字符串中引用和取消引用它,就像我在这里一样:

use DateTime;
my $dt = DateTime->now();
print "${\$dt->epoch }"; # both these
print "@{[$dt->epoch]}"; # examples work

但这看起来相当丑陋,所以我不推荐它。请改用第一种方法!

如果您仍然对它的工作原理感兴趣,您可能还需要查看这些Perl常见问题解答:


来自perlref

  

这是将子程序调用插入字符串的技巧:

print "My sub returned @{[mysub(1,2,3)]} that time.\n";
     

它的工作方式是在双引号中看到@ {...}   字符串,它被评估为一个块。该块创建对a的引用   匿名数组,包含对mysub(1,2,3)的调用结果。   因此,整个块返回对数组的引用,然后是该数组   由@ {...}取消引用并插入双引号字符串。这个   chicanery对任意表达也很有用:

print "That yields @{[$n + 5]} widgets\n";
     

类似地,返回对标量的引用的表达式可以是   通过$ {...}取消引用。因此,可以写出上述表达   为:

print "That yields ${\($n + 5)} widgets\n";

答案 1 :(得分:5)

$snap->volume_id不是属性,而是方法调用。虽然您可以在字符串中插入方法调用,但它是exceedingly ugly

要获取对象的所有属性,可以使用核心perl附带的模块Data::Dumper

use Data::Dumper;
print Dumper($object);

答案 2 :(得分:1)

坚持你展示的第一个样品。它看起来更干净,更容易阅读。

答案 3 :(得分:1)

我正在回答这个问题,因为我花了很长时间才发现这一点,我觉得其他人也可能会受益。

为了更好地打印对象,请使用Data :: Printer和p():

use DateTime;
use Data::Printer;
my $dt = DateTime->from_epoch( epoch => time );
p($dt);

答案 4 :(得分:0)

问题是$snap正在字符串中插入,但$snap是一个引用。正如perldoc perlref告诉我们:“将引用作为字符串产生它的指示对象类型,包括perlobj中描述的任何包祝福,以及以十六进制表示的数字地址。”

换句话说,在字符串中,您不能取消引用$snap。你的第一次尝试是正确的方法。

答案 5 :(得分:0)

PERL翻译器在引号内的深度感知有限。删除它们应该可以解决问题。或者只是将实际值加载到一个简单的变量中,您可以在引号内打印。如果你有包含指向其他对象的指针的对象,可能需要这样做:

SwissArmyChainSaw =/= PureMagic:
print("xxx".$this->{whatever}."rest of string\n");

答案 6 :(得分:0)

我同意大多数评论,请坚持串联以便于阅读。您可以使用

  

代替打印,以免使用“ \ n”。