6

我正在使用 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

有没有一种简单的方法可以在 print 中打印属性的值?

4

7 回答 7

11

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

要获取对象的所有属性,您可以使用Data::Dumper核心 perl 中包含的模块:

use Data::Dumper;
print Dumper($object);
于 2012-11-05T20:33:57.697 回答
9

不是你想要的方式。实际上,您正在做的$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";

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

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

同样,返回标量引用的表达式可以通过 ${...} 取消引用。因此,上面的表达式可以写成:

print "That yields ${\($n + 5)} widgets\n";
于 2012-11-05T20:34:16.417 回答
2

我正在回答这个问题,因为我花了很长时间才找到这个问题,而且我觉得其他人也可能从中受益。

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

use DateTime;
use Data::Printer;
my $dt = DateTime->from_epoch( epoch => time );
p($dt);
于 2013-08-02T18:38:19.020 回答
2

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

于 2012-11-05T20:24:57.763 回答
2

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

SwissArmyChainSaw =/= PureMagic:
print("xxx".$this->{whatever}."rest of string\n");
于 2016-05-22T04:00:04.777 回答
1

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

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

于 2012-11-05T20:34:41.433 回答
0

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

而不是打印以节省使用“\ n”。

于 2019-07-05T09:21:07.580 回答