File Coverage

blib/lib/Sub/HandlesVia/Toolkit/ObjectPad.pm
Criterion Covered Total %
statement 17 17 100.0
branch n/a
condition n/a
subroutine 6 6 100.0
pod n/a
total 23 23 100.0


line stmt bran cond sub pod time code
1 1     1   17 use 5.008;
  1         4  
2 1     1   6 use strict;
  1         2  
  1         37  
3 1     1   6 use warnings;
  1         2  
  1         76  
4              
5             package Sub::HandlesVia::Toolkit::ObjectPad;
6              
7             our $AUTHORITY = 'cpan:TOBYINK';
8             our $VERSION = '0.050000';
9              
10 1     1   471 use Sub::HandlesVia::Mite -all;
  1         3  
  1         6  
11             extends 'Sub::HandlesVia::Toolkit';
12              
13             around code_generator_for_attribute => sub {
14             my ( $next, $me, $target, $attr ) = ( shift, shift, @_ );
15            
16             if ( @$attr > 1 or $attr->[0] =~ /^\w/ ) {
17             return $me->$next( @_ );
18             }
19            
20             my $attrname = $attr->[0];
21            
22 1     1   187 use Object::Pad qw( :experimental(mop) );
  1         2  
  1         27  
23 1     1   716 use Object::Pad::MetaFunctions ();
  1         373  
  1         918  
24            
25             my $metaclass = Object::Pad::MOP::Class->for_class($target);
26             my $metafield = $metaclass->get_field( $attrname );
27            
28             my ( $get, $set, $slot, $get_is_lvalue );
29            
30             if ( $attrname =~ /^\$/ ) {
31            
32             $get = sub {
33             my ( $gen ) = ( shift );
34             sprintf( '$metafield->value(%s)', $gen->generate_self );
35             };
36             $set = sub {
37             my ( $gen, $value ) = ( shift, @_ );
38             sprintf( '( $metafield->value(%s) = %s )', $gen->generate_self, $value );
39             };
40             $slot = sub {
41             my ( $gen, $value ) = ( shift, @_ );
42             sprintf( '${ Object::Pad::MetaFunctions::ref_field(%s, %s) }', B::perlstring($attrname), $gen->generate_self );
43             };
44             $get_is_lvalue = false;
45             }
46             elsif ( $attrname =~ /^\@/ ) {
47            
48             $get = sub {
49             my ( $gen ) = ( shift );
50             sprintf( 'Object::Pad::MetaFunctions::ref_field(%s, %s)', B::perlstring($attrname), $gen->generate_self );
51             };
52             $set = sub {
53             my ( $gen, $value ) = ( shift, @_ );
54             sprintf( '( @{Object::Pad::MetaFunctions::ref_field(%s, %s)} = @{%s} )', B::perlstring($attrname), $gen->generate_self, $value );
55             };
56             $slot = sub {
57             my ( $gen, $value ) = ( shift, @_ );
58             sprintf( 'Object::Pad::MetaFunctions::ref_field(%s, %s)', B::perlstring($attrname), $gen->generate_self );
59             };
60             $get_is_lvalue = true;
61             }
62             elsif ( $attrname =~ /^\%/ ) {
63            
64             $get = sub {
65             my ( $gen ) = ( shift );
66             sprintf( 'Object::Pad::MetaFunctions::ref_field(%s, %s)', B::perlstring($attrname), $gen->generate_self );
67             };
68             $set = sub {
69             my ( $gen, $value ) = ( shift, @_ );
70             sprintf( '( %%{Object::Pad::MetaFunctions::ref_field(%s, %s)} = %%{%s} )', B::perlstring($attrname), $gen->generate_self, $value );
71             };
72             $slot = sub {
73             my ( $gen, $value ) = ( shift, @_ );
74             sprintf( 'Object::Pad::MetaFunctions::ref_field(%s, %s)', B::perlstring($attrname), $gen->generate_self );
75             };
76             $get_is_lvalue = true;
77             }
78             else {
79             croak 'Unexpected name for Object::Pad attribute: %s', $attr;
80             }
81            
82             require Sub::HandlesVia::CodeGenerator;
83             return 'Sub::HandlesVia::CodeGenerator'->new(
84             toolkit => $me,
85             target => $target,
86             attribute => $attrname,
87             env => { '$metafield' => \$metafield },
88             method_installer => sub { $metaclass->add_method( @_ ) }, # compile-time!
89             coerce => false,
90             generator_for_get => $get,
91             generator_for_set => $set,
92             generator_for_slot => $slot,
93             get_is_lvalue => $get_is_lvalue,
94             set_checks_isa => true,
95             set_strictly => false,
96             generator_for_default => sub {
97             my ( $gen, $handler ) = @_ or die;
98             return;
99             },
100             );
101             };
102              
103             1;
104