Если у класса нет атрибутов (объектных переменных), вы можете использовать переменную, возвращаемую from_json
в качестве объекта.
package Extended::JSON;
use strict;
use warnings;
use feature qw( say );
use JSON qw( from_json to_json );
sub open {
my ($class, $json) = @_;
return bless(from_json($json), $class);
}
sub write {
my ($self) = @_;
say to_json($self);
}
1;
Вы все равно можете использовать этот подход, если у класса есть атрибуты путем скрытия их, когда приходит время регенерировать JSON.
package Extended::JSON;
use strict;
use warnings;
use feature qw( say );
use JSON qw( from_json to_json );
sub open {
my ($class, $json) = @_;
my $self = bless(from_json($json), $class);
# $self->{_foo} = ...;
return $self;
}
sub write {
my ($self) = @_;
delete local @$self{ grep /^_/, keys(%$self) };
say to_json($self);
}
1;
. Выше требуется, чтобы верхний уровень JSON был «объектом» (ха sh), и это предотвращает определенные ключи от использования в этом объекте. Чтобы избежать этих ограничений, мы можем использовать overload .
package Extended::JSON;
use strict;
use warnings;
use feature qw( say );
use JSON qw( from_json to_json );
use overload '%{}' => \&data;
sub open {
my ($class, $json) = @_;
my $self = bless(\{}, $class);
$$self->{data} = from_json($json);
# $$self->{foo} = ...;
return $self;
}
sub write {
my ($self) = @_;
say to_json($$self->{data});
}
sub data {
my ($self) = @_;
return $$self->{data};
}
1;
Вышеописанное создает скалярный объект (в отличие от объекта на основе ха sh). При обработке ссылки как ссылки ha sh получаются данные, полученные из JSON, а при обработке ссылки как скалярной ссылки получается "реальный" объект.
$ perl -e'
use Extended::JSON qw( );
my $o = Extended::JSON->open(q{{"a":123}});
CORE::say $o->{a};
$o->write;
'
123
{"a":123}