]> git.vpit.fr Git - perl/modules/Lexical-Types.git/commitdiff
Allow skipping declarations by returning an empty list from the mangler
authorVincent Pit <vince@profvince.com>
Wed, 25 Feb 2009 09:27:01 +0000 (10:27 +0100)
committerVincent Pit <vince@profvince.com>
Wed, 25 Feb 2009 09:27:01 +0000 (10:27 +0100)
Types.xs
lib/Lexical/Types.pm
t/10-args.t

index ebfb8a7f1376c939021de932b31334a7245d32b9..9baa8da22f7f4883d51adfaf13ed83f5fdc8621a 100644 (file)
--- 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;
 }
 
index 29a5a0dbad80267ddc640ee17b7ec817dcd74aec..138fcf588cb0187cc61da5646fd8a6997ae5ceab 100644 (file)
@@ -74,14 +74,29 @@ If a plain scalar C<$prefix> is passed as the value, the C<TYPEDSCALAR> 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<undef>, 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<undef>, 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<Foo>) 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>.
 
index dddcea9b446ced080c33303d3b19dc6ad60fc6dd..879dadd04deda260b7d1ad2e7f8ce52ae6436119 100644 (file)
@@ -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;