确定提供转换为 JSON 的驼鹿类型

Determine the Moose Type for providing conversion to JSON

我有一个class, MyClass:

package MyClass;
use Moose;

has 'IntegerMember' => (
    is => 'rw',
    isa => 'Int'
);

has 'BooleanMember' => (
    is => 'rw',
    isa => 'Bool'
);

sub TO_JSON {
    my $self = shift;
    return { % { $self } };
}

当前,当我实例化 MyClass 并将新对象传递给 json_encoder 时,我得到了按预期返回的 JSON 字符串。我希望将 perl 布尔值 ( 1,0 ) 转换为 ( true, false ),但这不是 JSON 模块的设计方式:

use JSON;
use MyClass;

my $object_to_encode = MyClass->new ( 
    IntegerMember => 10,
    BooleanMember => 1
);
my $json_encoder = JSON->new->convert_blessed;
my $json_data = $json_encoder->encode( $object_to_encode );

在 MyClass 中,我想改进我的 TO_JSON 子例程以提供任何 Moose 'Bool' 成员从( 1 或 0 )到( true 或 false )的转换:

sub TO_JSON {
    my $self = shift;
    for my $member ( %$self ) {
        if {
            # Convert '1' to 'true' if Moose Type is 'Bool'
        } else {
            # Keep the member as is
        }
    }
}

如何在遍历 MyClass 成员时确定 Moose 类型,以便提供转换机制?

这是一种方法:

package MyClass;
use Moose;

has 'IntegerMember' => (
    is => 'rw',
    isa => 'Int'
);

has 'BooleanMember' => (
    is => 'rw',
    isa => 'Bool'
);

sub TO_JSON {
    my $self = shift;
    my $meta = $self->meta;
    my $result = {};
    for my $attr ($meta->get_all_attributes) {
        my $name = $attr->name;
        my $value = $attr->get_value($self);
        my $type = $attr->type_constraint;
        if ($type && $type->equals('Bool')) {
            $value = $value ?  : \ 0;
        }
        $result->{$name} = $value;
    }
    return $result;
}

1

我们使用 metaclass object (accessible via ->meta) to introspect the class and get a list of all attributes (in the form of meta-attribute objects).

对于每个属性,我们获取名称、当前值和 type constraint(如果有)。如果类型是 Bool,我们将值转换为 </code> 或 <code>[=16=]。 JSON 模块理解这些值并将它们转换为 truefalse.

还有一个测试程序:

use strict;
use warnings;
use JSON::MaybeXS;
use MyClass;

my $object_to_encode = MyClass->new ( 
    IntegerMember => 10,
    BooleanMember => 1
);
my $json_encoder = JSON->new->convert_blessed;
my $json_data = $json_encoder->encode( $object_to_encode );

print "Result: $json_data\n";

输出:

Result: {"IntegerMember":10,"BooleanMember":true}