Bot-Cobalt
view release on metacpan or search on metacpan
lib/Bot/Cobalt/Serializer.pm view on Meta::CPAN
}
sub _check_if_avail {
my ($self, $type) = @_;
my $module;
return unless $module = $self->_types->{$type};
{
local $@;
eval "require $module";
return if $@;
}
return $module
}
sub _read_serialized {
my ($self, $path, $opts) = @_;
return unless defined $path;
my $lock = 1;
if (defined $opts && ref $opts && reftype $opts eq 'HASH') {
$lock = $opts->{Locking} if defined $opts->{Locking};
}
if (blessed $path && $path->can('slurp_utf8')) {
return $path->slurp_utf8
} else {
open(my $in_fh, '<:encoding(UTF-8)', $path)
or confess "open failed for $path: $!";
if ($lock) {
flock($in_fh, LOCK_SH)
or confess "LOCK_SH failed for $path: $!";
}
my $data = join '', <$in_fh>;
flock($in_fh, LOCK_UN) if $lock;
close($in_fh)
or carp "close failed for $path: $!";
return $data
}
}
sub _write_serialized {
my ($self, $path, $data, $opts) = @_;
return unless $path and defined $data;
my $lock = 1;
my $timeout = 2;
if (defined $opts && ref $opts && reftype $opts eq 'HASH') {
$lock = $opts->{Locking} if defined $opts->{Locking};
$timeout = $opts->{Timeout} if $opts->{Timeout};
}
open(my $out_fh, '>>:encoding(UTF-8)', $path)
or confess "open failed for $path: $!";
if ($lock) {
my $timer = 0;
until ( flock $out_fh, LOCK_EX | LOCK_NB ) {
confess "Failed writefile lock ($path), timed out ($timeout)"
if $timer > $timeout;
sleep 0.01;
$timer += 0.01;
}
}
seek($out_fh, 0, 0)
or confess "seek failed for $path: $!";
truncate($out_fh, 0)
or confess "truncate failed for $path";
print $out_fh $data;
flock($out_fh, LOCK_UN) if $lock;
close($out_fh)
or carp "close failed for $path: $!";
return 1
}
1;
__END__
=pod
=head1 NAME
Bot::Cobalt::Serializer - Bot::Cobalt serialization wrapper
=head1 SYNOPSIS
use Bot::Cobalt::Serializer;
## Spawn a YAML (1.1) handler:
my $serializer = Bot::Cobalt::Serializer->new;
## Spawn a JSON handler:
my $serializer = Bot::Cobalt::Serializer->new('JSON');
## ...same as:
my $serializer = Bot::Cobalt::Serializer->new( Format => 'JSON' );
## Serialize some data to our Format:
my $ref = { Stuff => { Things => [ 'a', 'b'] } };
my $frozen = $serializer->freeze( $ref );
## Turn it back into a Perl data structure:
my $thawed = $serializer->thaw( $frozen );
lib/Bot/Cobalt/Serializer.pm view on Meta::CPAN
=item *
B<YAML> - YAML1.0 via L<YAML::Syck>
=item *
B<YAMLXS> - YAML1.1 via L<YAML::XS> I<(default)>
=item *
B<JSON> - JSON via L<JSON::MaybeXS>
=back
The default is YAML I<(YAML Ain't Markup Language)> 1.1 (B<YAMLXS>)
YAML is very powerful, and the appearance of the output makes it easy for
humans to read and edit.
JSON is a more simplistic format, often more suited for network transmission
and talking to other networked apps. JSON is noticably faster than YAML.
=head2 freeze
Turn the specified reference I<$ref> into the configured B<Format>.
my $frozen = $serializer->freeze($ref);
Upon success returns a scalar containing the serialized format, suitable for
saving to disk, transmission, etc.
=head2 thaw
Turn the specified serialized data (stored in a scalar) back into a Perl
data structure.
my $ref = $serializer->thaw($data);
(Try L<Data::Dumper> if you're not sure what your data actually looks like.)
=head2 writefile
L</freeze> the specified C<$ref> and write the serialized data to C<$path>
$serializer->writefile($path, $ref);
Will croak with a stack trace if the specified path/data could not be
written to disk due to an error.
Locks the file by default; blocks for up to 2 seconds attempting to
gain a lock. You can turn this behavior off entirely:
$serializer->writefile($path, $ref, { Locking => 0 });
... or change the lock timeout (defaults to 2 seconds):
$serializer->writefile($path, $ref,
{ Locking => 1, Timeout => 5 }
);
=head2 readfile
Read the serialized file at the specified C<$path> (if possible) and
L</thaw> the data structures back into a reference.
my $ref = $serializer->readfile($path);
By default, attempts to gain a shared (LOCK_SH) lock on the file in a
blocking manner.
You can turn this behavior off:
$serializer->readfile($path, { Locking => 0 });
Will croak with a stack trace if $path cannot be read or deserialized.
=head2 version
Obtains the backend serializer and its VERSION for the current instance.
my ($module, $modvers) = $serializer->version;
Returns a list of two values: the module name and its version.
## via Devel::REPL:
$ Bot::Cobalt::Serializer->new->version
$VAR1 = 'YAML::Syck';
$VAR2 = 1.19;
=head1 SEE ALSO
=over
=item *
L<YAML::Syck> -- YAML1.0: L<http://yaml.org/spec/1.0/>
=item *
L<YAML::XS> -- YAML1.1: L<http://yaml.org/spec/1.1/>
=item *
L<JSON>, L<JSON::MaybeXS> -- JSON: L<http://www.json.org/>
=back
=head1 AUTHOR
Jon Portnoy <avenj@cobaltirc.org>
=cut
( run in 1.395 second using v1.01-cache-2.11-cpan-39bf76dae61 )