File Coverage

blib/lib/Venus/Box.pm
Criterion Covered Total %
statement 36 43 83.7
branch 9 18 50.0
condition 2 5 40.0
subroutine 10 11 90.9
pod 0 4 0.0
total 57 81 70.3


line stmt bran cond sub pod time code
1             package Venus::Box;
2              
3 2     2   40 use 5.018;
  2         6  
4              
5 2     2   10 use strict;
  2         4  
  2         54  
6 2     2   9 use warnings;
  2         4  
  2         48  
7              
8 2     2   9 use Venus::Class 'with';
  2         4  
  2         9  
9              
10             with 'Venus::Role::Buildable';
11             with 'Venus::Role::Proxyable';
12              
13             # BUILDERS
14              
15             sub build_arg {
16 0     0 0 0 my ($self, $data) = @_;
17              
18             return {
19 0         0 value => $data,
20             };
21             }
22              
23             sub build_args {
24 6     6 0 14 my ($self, $data) = @_;
25              
26 6 50 33     36 if (keys %$data == 1 && exists $data->{value}) {
27 6         33 return $data;
28             }
29             return {
30 0         0 value => $data,
31             };
32             }
33              
34             sub build_self {
35 6     6 0 8 my ($self, $data) = @_;
36              
37 6         31 require Venus::Type;
38              
39 6   50     19 $data //= {};
40              
41 6         39 $self->{value} = Venus::Type->new(value => $data->{value})->deduce;
42              
43 6         27 return $self;
44             }
45              
46             sub build_proxy {
47 3     3 0 7 my ($self, $package, $method, @args) = @_;
48              
49 3         9 require Scalar::Util;
50              
51 3         6 my $value = $self->{value};
52              
53 3 50       10 if (not(Scalar::Util::blessed($value))) {
54 0         0 require Venus::Error;
55 0         0 return Venus::Error->throw(
56             "$package can only operate on objects, not $value"
57             );
58             }
59 3 100       18 if (!$value->can($method)) {
60 2 50       10 if (my $handler = $self->can("__handle__${method}")) {
    0          
61 2     2   15 return sub {$self->$handler(@args)};
  2         6  
62             }
63             elsif (!$value->can('AUTOLOAD')) {
64 0         0 return undef;
65             }
66             }
67             return sub {
68 1     1   2 local $_ = $value;
69 1         5 my $result = [
70             $value->$method(@args)
71             ];
72 1 50       5 $result = $result->[0] if @$result == 1;
73 1 50       5 if (Scalar::Util::blessed($result)) {
74 0 0       0 return not(UNIVERSAL::isa($result, 'Venus::Box'))
75             ? ref($self)->new(value => $result)
76             : $result;
77             }
78             else {
79 1         4 require Venus::Type;
80 1         18 return ref($self)->new(
81             value => Venus::Type->new(value => $result)->deduce
82             );
83             }
84 1         7 };
85             }
86              
87             # METHODS
88              
89             sub __handle__unbox {
90 2     2   5 my ($self, $code, @args) = @_;
91 2 100       17 return $code ? $self->$code(@args)->{value} : $self->{value};
92             }
93              
94             1;
95              
96              
97              
98             =head1 NAME
99              
100             Venus::Box - Box Class
101              
102             =cut
103              
104             =head1 ABSTRACT
105              
106             Box Class for Perl 5
107              
108             =cut
109              
110             =head1 SYNOPSIS
111              
112             package main;
113              
114             use Venus::Box;
115              
116             my $box = Venus::Box->new(
117             value => {},
118             );
119              
120             # $box->keys->count->unbox;
121              
122             =cut
123              
124             =head1 DESCRIPTION
125              
126             This package provides a pure Perl boxing mechanism for wrapping objects and
127             values, and chaining method calls across all objects.
128              
129             =cut
130              
131             =head1 INTEGRATES
132              
133             This package integrates behaviors from:
134              
135             L
136              
137             L
138              
139             =cut
140              
141             =head1 METHODS
142              
143             This package provides the following methods:
144              
145             =cut
146              
147             =head2 unbox
148              
149             unbox(Str $method, Any @args) (Any)
150              
151             The unbox method returns the un-boxed underlying object. This is a virtual
152             method that dispatches to C<__handle__unbox>. This method supports dispatching,
153             i.e. providing a method name and arguments whose return value will be acted on
154             by this method.
155              
156             I>
157              
158             =over 4
159              
160             =item unbox example 1
161              
162             # given: synopsis;
163              
164             my $unbox = $box->unbox;
165              
166             # bless({ value => {} }, "Venus::Hash")
167              
168             =back
169              
170             =over 4
171              
172             =item unbox example 2
173              
174             # given: synopsis;
175              
176             my $unbox = $box->unbox('count');
177              
178             # 0
179              
180             =back
181              
182             =cut
183              
184             =head1 AUTHORS
185              
186             Awncorp, C
187              
188             =cut
189              
190             =head1 LICENSE
191              
192             Copyright (C) 2000, Al Newkirk.
193              
194             This program is free software, you can redistribute it and/or modify it under
195             the terms of the Apache license version 2.0.
196              
197             =cut