我正在使用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
是否有一种简单的方法可以在打印内打印属性值?
答案 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”。