File Coverage

blib/lib/Object/Stash/Util.pm
Criterion Covered Total %
statement 13 14 92.8
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 17 18 94.4


line stmt bran cond sub pod time code
1             package Object::Stash::Util;
2              
3 1     1   29076 use 5.010;
  1         3  
  1         36  
4 1     1   6 use strict;
  1         1  
  1         36  
5 1     1   830 use utf8;
  1         9  
  1         5  
6              
7             our @EXPORT_OK;
8             BEGIN {
9 1     1   93 $Object::Stash::AUTHORITY = 'cpan:TOBYINK';
10 1         2 $Object::Stash::VERSION = '0.006';
11            
12 1         2 @EXPORT_OK = qw/
13             has_stash make_method make_stash
14             /;
15            
16 1         1820 require Object::Role;
17 0           require Object::Stash;
18             }
19              
20             use Carp qw/croak/;
21              
22             use base qw/Exporter Object::Role/;
23              
24             our $caller_level = 0;
25              
26             sub make_method
27             {
28             my $stash = shift;
29             my $method = shift;
30             my $options = { @_ };
31             my $package;
32              
33             if ($stash =~ m{^(.+)::([^:]+)$})
34             {
35             $package = $1;
36             $stash = $2;
37             }
38             else
39             {
40             $package = caller($caller_level);
41             }
42            
43             my $stash_coderef = do {
44             no strict 'refs';
45             \&{ "$package\::$stash" };
46             };
47              
48             my $slot = $options->{'slot'} // $method;
49             my $default = sub { undef };
50             if (exists $options->{'default'})
51             {
52             $default = (ref $options->{'default'} eq 'CODE') ?
53             $options->{'default'} :
54             sub { $options->{'default'} } ;
55             }
56            
57             my $coderef =
58             ($options->{'is'} eq 'ro') ?
59             sub
60             {
61             my $self = shift;
62             my $hash = $self->$stash_coderef;
63             $hash->{$slot} = $default->($self) unless exists $hash->{$slot};
64             $hash->{$slot};
65             } :
66             sub :lvalue
67             {
68             my $self = shift;
69             my $hash = $self->$stash_coderef;
70             $hash->{$slot} = shift if @_;
71             $hash->{$slot} = $default->($self) unless exists $hash->{$slot};
72             $hash->{$slot};
73             } ;
74            
75             __PACKAGE__ -> install_method(
76             $method => $coderef,
77             do { my $caller = caller($caller_level) },
78             );
79             }
80              
81             sub make_stash
82             {
83             my ($stash, @args) = @_;
84             my $package;
85              
86             if ($stash =~ m{^(.+)::([^:]+)$})
87             {
88             $package = $1;
89             $stash = $2;
90             }
91             else
92             {
93             $package = caller($caller_level);
94             }
95            
96             no strict 'refs';
97             Object::Stash->import(-method => [$stash], -package => $package, @args)
98             unless Object::Stash::is_stash(\&{"$package\::$stash"});
99             }
100              
101             sub has_stash
102             {
103             my ($stash_name, %args) = @_;
104             my $old_caller_level;
105             local $caller_level = $old_caller_level + 1;
106            
107             make_stash($stash_name, -type => ($args{isa} // 'object'));
108            
109             if (ref $args{handles} eq 'ARRAY')
110             {
111             my @handles = @{ $args{handles} };
112             while (@handles)
113             {
114             my $method = shift @handles;
115             my $opts = (ref $handles[0] eq 'HASH') ? shift(@handles) : {};
116             make_method($stash_name, $method, %$opts);
117             }
118             }
119             elsif (ref $args{handles} eq 'HASH')
120             {
121             my %handles = %{ $args{handles} };
122             while (my ($method, $opts) = each %handles)
123             {
124             make_method($stash_name, $method, %$opts);
125             }
126             }
127             elsif (!ref $args{handles})
128             {
129             make_method($stash_name, $args{handles});
130             }
131            
132             return;
133             }
134              
135             __PACKAGE__
136             __END__