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