1

我有一些复杂的对象结构,我使用 Data::Printer 来检查它们。它不够有用的一种情况是:当一个对象(容器)具有另一个对象(子对象)的字段时,子对象仅作为类名出现在 DDP 的输出中。我还希望看到孩子的字符串化值。

让我们举个例子:

{
    package Child;
    use Moo;

    use overload '""' => "stringify";

    has 'value', is => 'ro';

    sub stringify {
        my $self = shift;
        return "<Child:" . $self->value . ">";
    }

}

{
    package Container;
    use Moo;

    has 'child', is => 'ro';
}

my $child_x = Child->new(value => 'x');
print "stringified child x: $child_x\n";

my $child_y = Child->new(value => 'y');
print "stringified child y: $child_y\n";

my $container_x = Container->new(child => $child_x);
my $container_y = Container->new(child => $child_y);

use DDP;
print "ddp x: " . p($container_x) . "\n";
print "ddp y: " . p($container_y) . "\n";

输出:

stringified child x: <Child:x>
stringified child y: <Child:y>
ddp x: Container  {
    Parents       Moo::Object
    public methods (2) : child, new
    private methods (0)
    internals: {
        child   Child                  # <- note this
    }
}
ddp y: Container  {
    Parents       Moo::Object
    public methods (2) : child, new
    private methods (0)
    internals: {
        child   Child                  # <- and this
    }
}

如您所见,孩子在输出中无法区分。我想在那个地方看到字符串化,除了类名之外,或者代替类名。

4

2 回答 2

2

正如 Dave 指出的,我们可以在导入 Data::Printer 时定义过滤器:

use DDP filters => {
    'Child' => sub { "$_[0]" }
};

更好的方法是使用_data_printer功能(因为每次导入 DDP 时都要输入过滤器定义很痛苦):

{
    package Child;
    ...

    sub _data_printer {
        my $self = shift;
        return "$self";
    }
}

两种方式都在内部显示字符串化的值:

ddp x: Container  {
    Parents       Moo::Object
    public methods (2) : child, new
    private methods (0)
    internals: {
        child   <Child:x>
    }
}
于 2013-07-02T14:20:00.873 回答
2

根据Data::Printer docs

Data::Printer 让您能够使用过滤器覆盖任何类型的数据显示。过滤器放置在散列上,其中键是类型或类名,值是接收两个参数的匿名子:作为第一个参数的项目本身和属性 hashref(以防您的过滤器想要从中读取) . 这使您可以快速覆盖 D​​ata::Printer 处理和显示数据类型,特别是对象的方式。

于 2013-07-02T14:07:50.840 回答