From: Vincent Pit Date: Wed, 25 Feb 2009 09:27:01 +0000 (+0100) Subject: Allow skipping declarations by returning an empty list from the mangler X-Git-Tag: v0.02~7 X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2FLexical-Types.git;a=commitdiff_plain;h=7cff22e4b5498f801c1d9be1dcab213a39395d0a Allow skipping declarations by returning an empty list from the mangler --- diff --git a/Types.xs b/Types.xs index ebfb8a7..9baa8da 100644 --- a/Types.xs +++ b/Types.xs @@ -201,7 +201,11 @@ STATIC OP *lt_ck_padany(pTHX_ OP *o) { SPAGAIN; if (items > 2) croak(__PACKAGE__ " mangler should return zero, one or two scalars, but got %d", items); - if (items) { + if (items == 0) { + SvREFCNT_dec(orig_pkg); + SvREFCNT_dec(orig_meth); + goto skip; + } else { SV *rsv; if (items > 1) { rsv = POPs; @@ -223,6 +227,7 @@ STATIC OP *lt_ck_padany(pTHX_ OP *o) { PL_ppaddr[OP_PADSV] = lt_pp_padsv; } +skip: return o; } diff --git a/lib/Lexical/Types.pm b/lib/Lexical/Types.pm index 29a5a0d..138fcf5 100644 --- a/lib/Lexical/Types.pm +++ b/lib/Lexical/Types.pm @@ -74,14 +74,29 @@ If a plain scalar C<$prefix> is passed as the value, the C method i =item * -If the value given is a code reference C<$mangler>, it will be called at compile-time with arguments C<'Foo'> and C<'TYPEDSCALAR'> and is expected to return the desired package and method name (in that order). -If any of those is C, the default value will be used instead. +If the value given is a code reference C<$mangler>, it will be called at compile-time with arguments C<'Foo'> and C<'TYPEDSCALAR'> and is expected to return : + +=over 4 + +=item * + +either an empty list, in which case the current typed lexical definition will be skipped (thus it won't be altered to trigger a run-time hook) ; + + use Lexical::Types as => sub { return $_[0] =~ /Str/ ? () : @_ }; + my Str $x; # nothing special + my Int $y; # calls Int->TYPEDSCALAR + +=item * + +or the desired package and method name, in that order (if any of those is C, the default value will be used instead). use Lexical::Types as => sub { 'My', 'new_' . lc($_[0]) }; my Str $x; # the coderef indicates to call My->new_str =back +=back + The initializer method receives an alias to the pad entry of C<$x> in C<$_[1]> and the original type name (C) in C<$_[2]>. You can either edit C<$_[1]> in place, in which case you should return an empty list, or return a new scalar that will be copied into C<$x>. diff --git a/t/10-args.t b/t/10-args.t index dddcea9..879dadd 100644 --- a/t/10-args.t +++ b/t/10-args.t @@ -3,7 +3,7 @@ use strict; use warnings; -use Test::More tests => 11 + 6; +use Test::More tests => 12 + 6; { package Lexical::Types::Test::LTT; @@ -47,6 +47,12 @@ use Test::More tests => 11 + 6; is $x, __LINE__-1, 'as => string, with trailing ::'; } +{ + use Lexical::Types as => sub { return }; + my LTT $x; + is $x, undef, 'as => code, returning nothing'; +} + { use Lexical::Types as => sub { 'Lexical::Types::Test::LTT' }; my LTT $x;