File Coverage

blib/lib/YAML/Old/Types.pm
Criterion Covered Total %
statement 109 156 69.8
branch 33 50 66.0
condition 3 5 60.0
subroutine 14 22 63.6
pod n/a
total 159 233 68.2


line stmt bran cond sub pod time code
1             package YAML::Old::Types;
2              
3 35     35   187 use YAML::Old::Mo;
  35         64  
  35         412  
4 35     35   210 use YAML::Old::Node;
  35         97  
  35         2772  
5              
6             # XXX These classes and their APIs could still use some refactoring,
7             # but at least they work for now.
8             #-------------------------------------------------------------------------------
9             package YAML::Old::Type::blessed;
10              
11 35     35   186 use YAML::Old::Mo; # XXX
  35         59  
  35         526  
12              
13             sub yaml_dump {
14 27     27   53 my $self = shift;
15 27         56 my ($value) = @_;
16 27         118 my ($class, $type) = YAML::Old::Mo::Object->node_info($value);
17 35     35   207 no strict 'refs';
  35         112  
  35         24726  
18 27         101 my $kind = lc($type) . ':';
19 27   66     42 my $tag = ${$class . '::ClassTag'} ||
20             "!perl/$kind$class";
21 27 100       105 if ($type eq 'REF') {
    100          
22 1         7 YAML::Old::Node->new(
23 1         4 {(&YAML::VALUE, ${$_[0]})}, $tag
24             );
25             }
26             elsif ($type eq 'SCALAR') {
27 7         154 $_[1] = $$value;
28 7         44 YAML::Old::Node->new($_[1], $tag);
29             } else {
30 19         121 YAML::Old::Node->new($value, $tag);
31             }
32             }
33              
34             #-------------------------------------------------------------------------------
35             package YAML::Old::Type::undef;
36              
37             sub yaml_dump {
38 0     0   0 my $self = shift;
39             }
40              
41             sub yaml_load {
42 0     0   0 my $self = shift;
43             }
44              
45             #-------------------------------------------------------------------------------
46             package YAML::Old::Type::glob;
47              
48             sub yaml_dump {
49 5     5   8 my $self = shift;
50 5         21 my $ynode = YAML::Old::Node->new({}, '!perl/glob:');
51 5         13 for my $type (qw(PACKAGE NAME SCALAR ARRAY HASH CODE IO)) {
52 35         33 my $value = *{$_[0]}{$type};
  35         75  
53 35 100       82 $value = $$value if $type eq 'SCALAR';
54 35 100       67 if (defined $value) {
55 17 50       32 if ($type eq 'IO') {
56 0         0 my @stats = qw(device inode mode links uid gid rdev size
57             atime mtime ctime blksize blocks);
58 0         0 undef $value;
59 0         0 $value->{stat} = YAML::Old::Node->new({});
60 0 0       0 if ($value->{fileno} = fileno(*{$_[0]})) {
  0         0  
61 0         0 local $^W;
62 0         0 map {$value->{stat}{shift @stats} = $_} stat(*{$_[0]});
  0         0  
  0         0  
63 0         0 $value->{tell} = tell(*{$_[0]});
  0         0  
64             }
65             }
66 17         70 $ynode->{$type} = $value;
67             }
68             }
69 5         20 return $ynode;
70             }
71              
72             sub yaml_load {
73 4     4   20 my $self = shift;
74 4         7 my ($node, $class, $loader) = @_;
75 4         6 my ($name, $package);
76 4 100       14 if (defined $node->{NAME}) {
77 3         7 $name = $node->{NAME};
78 3         8 delete $node->{NAME};
79             }
80             else {
81 1         4 $loader->warn('YAML_LOAD_WARN_GLOB_NAME');
82 1         1080 return undef;
83             }
84 3 100       8 if (defined $node->{PACKAGE}) {
85 2         5 $package = $node->{PACKAGE};
86 2         3 delete $node->{PACKAGE};
87             }
88             else {
89 1         3 $package = 'main';
90             }
91 35     35   215 no strict 'refs';
  35         80  
  35         14466  
92 3 100       10 if (exists $node->{SCALAR}) {
93 2         4 *{"${package}::$name"} = \$node->{SCALAR};
  2         9  
94 2         4 delete $node->{SCALAR};
95             }
96 3         7 for my $elem (qw(ARRAY HASH CODE IO)) {
97 12 100       31 if (exists $node->{$elem}) {
98 2 50       5 if ($elem eq 'IO') {
99 0         0 $loader->warn('YAML_LOAD_WARN_GLOB_IO');
100 0         0 delete $node->{IO};
101 0         0 next;
102             }
103 2         4 *{"${package}::$name"} = $node->{$elem};
  2         7  
104 2         6 delete $node->{$elem};
105             }
106             }
107 3         15 for my $elem (sort keys %$node) {
108 1         4 $loader->warn('YAML_LOAD_WARN_BAD_GLOB_ELEM', $elem);
109             }
110 3         901 return *{"${package}::$name"};
  3         23  
111             }
112              
113             #-------------------------------------------------------------------------------
114             package YAML::Old::Type::code;
115              
116             my $dummy_warned = 0;
117             my $default = '{ "DUMMY" }';
118              
119             sub yaml_dump {
120 6     6   11 my $self = shift;
121 6         9 my $code;
122 6         18 my ($dumpflag, $value) = @_;
123 6         33 my ($class, $type) = YAML::Old::Mo::Object->node_info($value);
124 6         20 my $tag = "!perl/code";
125 6 100       32 $tag .= ":$class" if defined $class;
126 6 100       20 if (not $dumpflag) {
127 1         3 $code = $default;
128             }
129             else {
130 5 100       19 bless $value, "CODE" if $class;
131 35     35   225 eval { use B::Deparse };
  35         61  
  35         52763  
  5         10  
132 5 50       92 return if $@;
133 5         214 my $deparse = B::Deparse->new();
134 5         10 eval {
135 5         26 local $^W = 0;
136 5         3449 $code = $deparse->coderef2text($value);
137             };
138 5 50       23 if ($@) {
139 0 0       0 warn YAML::YAML_DUMP_WARN_DEPARSE_FAILED() if $^W;
140 0         0 $code = $default;
141             }
142 5 100       17 bless $value, $class if $class;
143 5         30 chomp $code;
144 5         27 $code .= "\n";
145             }
146 6         14 $_[2] = $code;
147 6         47 YAML::Old::Node->new($_[2], $tag);
148             }
149              
150             sub yaml_load {
151 4     4   8 my $self = shift;
152 4         10 my ($node, $class, $loader) = @_;
153 4 50       30 if ($loader->load_code) {
154 0         0 my $code = eval "package main; sub $node";
155 0 0       0 if ($@) {
156 0         0 $loader->warn('YAML_LOAD_WARN_PARSE_CODE', $@);
157 0     0   0 return sub {};
  0         0  
158             }
159             else {
160 0 0       0 CORE::bless $code, $class if $class;
161 0         0 return $code;
162             }
163             }
164             else {
165 4 50   0   15 return CORE::bless sub {}, $class if $class;
  0         0  
166 4     0   39 return sub {};
  0         0  
167             }
168             }
169              
170             #-------------------------------------------------------------------------------
171             package YAML::Old::Type::ref;
172              
173             sub yaml_dump {
174 32     32   44 my $self = shift;
175 32         72 YAML::Old::Node->new({(&YAML::VALUE, ${$_[0]})}, '!perl/ref')
  32         163  
176             }
177              
178             sub yaml_load {
179 0     0   0 my $self = shift;
180 0         0 my ($node, $class, $loader) = @_;
181 0 0       0 $loader->die('YAML_LOAD_ERR_NO_DEFAULT_VALUE', 'ptr')
182             unless exists $node->{&YAML::VALUE};
183 0         0 return \$node->{&YAML::VALUE};
184             }
185              
186             #-------------------------------------------------------------------------------
187             package YAML::Old::Type::regexp;
188              
189             # XXX Be sure to handle blessed regexps (if possible)
190             sub yaml_dump {
191 0     0   0 die "YAML::Old::Type::regexp::yaml_dump not currently implemented";
192             }
193              
194             use constant _QR_TYPES => {
195 2         23 '' => sub { qr{$_[0]} },
196 0         0 x => sub { qr{$_[0]}x },
197 0         0 i => sub { qr{$_[0]}i },
198 0         0 s => sub { qr{$_[0]}s },
199 4         21 m => sub { qr{$_[0]}m },
200 0         0 ix => sub { qr{$_[0]}ix },
201 0         0 sx => sub { qr{$_[0]}sx },
202 0         0 mx => sub { qr{$_[0]}mx },
203 0         0 si => sub { qr{$_[0]}si },
204 0         0 mi => sub { qr{$_[0]}mi },
205 0         0 ms => sub { qr{$_[0]}sm },
206 0         0 six => sub { qr{$_[0]}six },
207 0         0 mix => sub { qr{$_[0]}mix },
208 0         0 msx => sub { qr{$_[0]}msx },
209 0         0 msi => sub { qr{$_[0]}msi },
210 0         0 msix => sub { qr{$_[0]}msix },
211 35     35   345 };
  35         73  
  35         17966  
212              
213             sub yaml_load {
214 6     6   9 my $self = shift;
215 6         10 my ($node, $class) = @_;
216 6 50       27 return qr{$node} unless $node =~ /^\(\?([\^\-xism]*):(.*)\)\z/s;
217 6         14 my ($flags, $re) = ($1, $2);
218 6         14 $flags =~ s/-.*//;
219 6         14 $flags =~ s/^\^//;
220 6   50 0   17 my $sub = _QR_TYPES->{$flags} || sub { qr{$_[0]} };
  0            
221 6         13 my $qr = &$sub($re);
222 6 100       21 bless $qr, $class if length $class;
223 6         24 return $qr;
224             }
225              
226             1;