From: Toby Inkster Date: Fri, 5 Apr 2013 17:56:39 +0000 (+0100) Subject: inlining for overloaded object isa/coerce X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=gitmo%2FMoo.git;a=commitdiff_plain;h=2f425b5770149d4ed2e59da001c3be052cbd6bc1 inlining for overloaded object isa/coerce --- diff --git a/lib/Method/Generate/Accessor.pm b/lib/Method/Generate/Accessor.pm index e5ca31d..135ec69 100644 --- a/lib/Method/Generate/Accessor.pm +++ b/lib/Method/Generate/Accessor.pm @@ -389,6 +389,7 @@ sub _generate_isa_check { sub _generate_call_code { my ($self, $name, $type, $values, $sub) = @_; + $sub = \&{$sub} if blessed($sub); # coderef if blessed if (my $quoted = quoted_from_sub($sub)) { my $code = $quoted->[1]; if (my $captures = $quoted->[2]) { diff --git a/t/overloaded-coderefs.t b/t/overloaded-coderefs.t new file mode 100644 index 0000000..c4b1d6b --- /dev/null +++ b/t/overloaded-coderefs.t @@ -0,0 +1,54 @@ +use strict; +use warnings; +use Test::More; + +{ + package Dark::Side; + use overload + q[&{}] => sub { shift->to_code }, + fallback => 1; + sub new { + my $class = shift; + bless \$_[0], $class; + } + sub to_code { + my $self = shift; + eval "sub { $$self }"; + } +} + +{ + package The::Force; + use Sub::Quote; + use base 'Dark::Side'; + sub to_code { + my $self = shift; + return quote_sub $$self; + } +} + +my $darkside = Dark::Side->new('my $dummy = "join the dark side"; $_[0] * 2'); +is($darkside->(6), 12, 'check Dark::Side coderef'); + +my $theforce = The::Force->new('my $dummy = "use the force Luke"; $_[0] * 2'); +is($theforce->(6), 12, 'check The::Force coderef'); + +{ + package Doubleena; + use Moo; + has a => (is => "ro", coerce => $darkside, isa => sub { 1 }); + has b => (is => "ro", coerce => $theforce, isa => The::Force->new('my $z = "I am your father"')); +} + +my $o = Doubleena->new(a => 11, b => 12); +is($o->a, 22, 'non-Sub::Quoted inlined coercion overload works'); +is($o->b, 24, 'Sub::Quoted inlined coercion overload works'); + +use B::Deparse; +my $constructor = B::Deparse->new->coderef2text(Doubleena->can('new')); + +like($constructor, qr{use the force Luke}, 'Sub::Quoted coercion got inlined'); +unlike($constructor, qr{join the dark side}, 'non-Sub::Quoted coercion was not inlined'); +like($constructor, qr{I am your father}, 'Sub::Quoted isa got inlined'); + +done_testing;