App-Dex
view release on metacpan or search on metacpan
scripts/dex view on Meta::CPAN
The Constructor now supports all three YAML 1.2 Schemas, Failsafe, JSON and
Core. Additionally you can choose the schema for YAML 1.1 as C<YAML1_1>.
Too see what strings are resolved as booleans, numbers, null etc. look at
L<https://perlpunk.github.io/YAML-PP-p5/schema-examples.html>.
You can choose the Schema like this:
my $ypp = YAML::PP->new(schema => ['JSON']); # default is 'Core'
The Tags C<!!seq> and C<!!map> are still ignored for now.
It supports:
=over 4
=item Handling of Anchors/Aliases
Like in modules like L<YAML>, the Constructor will use references for mappings and
sequences, but obviously not for scalars.
L<YAML::XS> uses real aliases, which allows also aliasing scalars. I might add
an option for that since aliasing is now available in pure perl.
=item Boolean Handling
You can choose between C<'perl'> (1/'', currently default), C<'JSON::PP'> and
C<'boolean'>.pm for handling boolean types. That allows you to dump the data
structure with one of the JSON modules without losing information about
booleans.
=item Numbers
Numbers are created as real numbers instead of strings, so that they are
dumped correctly by modules like L<JSON::PP> or L<JSON::XS>, for example.
=item Complex Keys
Mapping Keys in YAML can be more than just scalars. Of course, you can't load
that into a native perl structure. The Constructor will stringify those keys
with L<Data::Dumper> instead of just returning something like
C<HASH(0x55dc1b5d0178)>.
Example:
use YAML::PP;
use JSON::PP;
my $ypp = YAML::PP->new;
my $coder = JSON::PP->new->ascii->pretty->allow_nonref->canonical;
my $yaml = <<'EOM';
complex:
?
?
a: 1
c: 2
: 23
: 42
EOM
my $data = $yppl->load_string($yaml);
say $coder->encode($data);
__END__
{
"complex" : {
"{'{a => 1,c => 2}' => 23}" : 42
}
}
=back
TODO:
=over 4
=item Parse Tree
I would like to generate a complete parse tree, that allows you to manipulate
the data structure and also dump it, including all whitespaces and comments.
The spec says that this is throwaway content, but I read that many people
wish to be able to keep the comments.
=back
=head2 YAML::PP::Dumper, YAML::PP::Emitter
The Dumper should be able to dump strings correctly, adding quotes
whenever a plain scalar would look like a special string, like C<true>,
or when it contains or starts with characters that are not allowed.
Most strings will be dumped as plain scalars without quotes. If they
contain special characters or have a special meaning, they will be dumped
with single quotes. If they contain control characters, including <"\n">,
they will be dumped with double quotes.
It will recognize JSON::PP::Boolean and boolean.pm objects and dump them
correctly.
Numbers which also have a C<PV> flag will be recognized as numbers and not
as strings:
my $int = 23;
say "int: $int"; # $int will now also have a PV flag
That means that if you accidentally use a string in numeric context, it will
also be recognized as a number:
my $string = "23";
my $something = $string + 0;
print $yp->dump_string($string);
# will be emitted as an integer without quotes!
The layout is like libyaml output:
key:
- a
- b
- c
---
- key1: 1
key2: 2
key3: 3
---
- - a1
- a2
- - b1
- b2
=head1 WHY
All the available parsers and loaders for Perl are behaving differently,
and more important, aren't conforming to the spec. L<YAML::XS> is
doing pretty well, but C<libyaml> only handles YAML 1.1 and diverges
a bit from the spec. The pure perl loaders lack support for a number of
features.
I was going over L<YAML>.pm issues end of 2016, integrating old patches
from rt.cpan.org and creating some pull requests myself. I realized
that it would be difficult to patch YAML.pm to parse YAML 1.1 or even 1.2,
and it would also break existing usages relying on the current behaviour.
In 2016 Ingy döt Net initiated two really cool projects:
=over 4
=item L<"YAML TEST SUITE">
=item L<"YAML EDITOR">
=back
These projects are a big help for any developer. So I got the idea
to write my own parser and started on New Year's Day 2017.
Without the test suite and the editor I would have never started this.
I also started another YAML Test project which allows one to get a quick
overview of which frameworks support which YAML features:
=over 4
=item L<"YAML TEST MATRIX">
scripts/dex view on Meta::CPAN
$value = $$value;
}
elsif ($type eq 'IO') {
if (defined $value) {
undef $value;
$value->{stat} = {};
if ($value->{fileno} = fileno(*{ $glob })) {
@{ $value->{stat} }{ @stats } = stat(*{ $glob });
$value->{tell} = tell *{ $glob };
}
}
}
$glob{ $type } = $value if defined $value;
}
return \%glob;
}
sub represent_regex {
my ($self, $regex) = @_;
$regex = "$regex";
if ($regex =~ m/^$qr_prefix(.*)\)\z/s) {
$regex = $1;
}
return $regex;
}
sub object {
my ($self, $data, $class) = @_;
return bless $data, $class;
}
1;
__END__
=pod
=encoding utf-8
=head1 NAME
YAML::PP::Schema::Perl - Schema for serializing perl objects and special types
=head1 SYNOPSIS
use YAML::PP;
# This can be dangerous when loading untrusted YAML!
my $yp = YAML::PP->new( schema => [qw/ + Perl /] );
# or
my $yp = YAML::PP->new( schema => [qw/ Core Perl /] );
my $yaml = $yp->dump_string(sub { return 23 });
# loading code references
# This is very dangerous when loading untrusted YAML!!
my $yp = YAML::PP->new( schema => [qw/ + Perl +loadcode /] );
my $code = $yp->load_string(<<'EOM');
--- !perl/code |
{
use 5.010;
my ($name) = @_;
say "Hello $name!";
}
EOM
$code->("Ingy");
=head1 DESCRIPTION
This schema allows you to load and dump perl objects and special types.
Please note that loading objects of arbitrary classes can be dangerous
in Perl. You have to load the modules yourself, but if an exploitable module
is loaded and an object is created, its C<DESTROY> method will be called
when the object falls out of scope. L<File::Temp> is an example that can
be exploitable and might remove arbitrary files.
Dumping code references is on by default, but not loading (because that is
easily exploitable since it's using string C<eval>).
=head2 Tag Styles
You can define the style of tags you want to support:
my $yp_perl_two_one = YAML::PP->new(
schema => [qw/ + Perl tags=!!perl+!perl /],
);
=over
=item C<!perl> (default)
Only C<!perl/type> tags are supported.
=item C<!!perl>
Only C<!!perl/type> tags are supported.
=item C<!perl+!!perl>
Both C<!perl/type> and C<!!perl/tag> are supported when loading. When dumping,
C<!perl/type> is used.
=item C<!!perl+!perl>
Both C<!perl/type> and C<!!perl/tag> are supported when loading. When dumping,
C<!!perl/type> is used.
=back
L<YAML>.pm, L<YAML::Syck> and L<YAML::XS> are using C<!!perl/type> when dumping.
L<YAML>.pm and L<YAML::Syck> are supporting both C<!perl/type> and
C<!!perl/type> when loading. L<YAML::XS> currently only supports the latter.
=head2 Allow only certain classes
Since v0.017
Blessing arbitrary objects can be dangerous. Maybe you want to allow blessing
only specific classes and ignore others. For this you have to instantiate
a Perl Schema object first and use the C<classes> option.
scripts/dex view on Meta::CPAN
(such as the L</shuffle> and L</sample> functions). If set to a CODE reference
it provides an alternative to perl's builtin C<rand()> function. When a new
random number is needed this function will be invoked with no arguments and is
expected to return a floating-point value, of which only the fractional part
will be used.
=head1 KNOWN BUGS
=head2 RT #95409
L<https://rt.cpan.org/Ticket/Display.html?id=95409>
If the block of code given to L</pairmap> contains lexical variables that are
captured by a returned closure, and the closure is executed after the block
has been re-used for the next iteration, these lexicals will not see the
correct values. For example:
my @subs = pairmap {
my $var = "$a is $b";
sub { print "$var\n" };
} one => 1, two => 2, three => 3;
$_->() for @subs;
Will incorrectly print
three is 3
three is 3
three is 3
This is due to the performance optimisation of using C<MULTICALL> for the code
block, which means that fresh SVs do not get allocated for each call to the
block. Instead, the same SV is re-assigned for each iteration, and all the
closures will share the value seen on the final iteration.
To work around this bug, surround the code with a second set of braces. This
creates an inner block that defeats the C<MULTICALL> logic, and does get fresh
SVs allocated each time:
my @subs = pairmap {
{
my $var = "$a is $b";
sub { print "$var\n"; }
}
} one => 1, two => 2, three => 3;
This bug only affects closures that are generated by the block but used
afterwards. Lexical variables that are only used during the lifetime of the
block's execution will take their individual values for each invocation, as
normal.
=head2 uniqnum() on oversized bignums
Due to the way that C<uniqnum()> compares numbers, it cannot distinguish
differences between bignums (especially bigints) that are too large to fit in
the native platform types. For example,
my $x = Math::BigInt->new( "1" x 100 );
my $y = $x + 1;
say for uniqnum( $x, $y );
Will print just the value of C<$x>, believing that C<$y> is a numerically-
equivalent value. This bug does not affect C<uniqstr()>, which will correctly
observe that the two values stringify to different strings.
=head1 SUGGESTED ADDITIONS
The following are additions that have been requested, but I have been reluctant
to add due to them being very simple to implement in perl
# How many elements are true
sub true { scalar grep { $_ } @_ }
# How many elements are false
sub false { scalar grep { !$_ } @_ }
=head1 SEE ALSO
L<Scalar::Util>, L<List::MoreUtils>
=head1 COPYRIGHT
Copyright (c) 1997-2007 Graham Barr <gbarr@pobox.com>. All rights reserved.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
Recent additions and current maintenance by
Paul Evans, <leonerd@leonerd.org.uk>.
=cut
1;
X86_64-LINUX-GNU-THREAD-MULTI_LIST_UTIL
$fatpacked{"x86_64-linux-gnu-thread-multi/List/Util/XS.pm"} = '#line '.(1+__LINE__).' "'.__FILE__."\"\n".<<'X86_64-LINUX-GNU-THREAD-MULTI_LIST_UTIL_XS';
package List::Util::XS;
use strict;
use warnings;
use List::Util;
our $VERSION = "1.59"; # FIXUP
$VERSION =~ tr/_//d; # FIXUP
1;
__END__
=head1 NAME
List::Util::XS - Indicate if List::Util was compiled with a C compiler
=head1 SYNOPSIS
use List::Util::XS 1.20;
=head1 DESCRIPTION
C<List::Util::XS> can be used as a dependency to ensure List::Util was
installed using a C compiler and that the XS version is installed.
( run in 0.622 second using v1.01-cache-2.11-cpan-d7a12ab2c7f )