1 package Lexical::Types;
12 Lexical::Types - Extend the semantics of typed lexicals.
30 package My::Types::Str;
32 sub new { bless { }, shift }
35 use Lexical::Types as => sub { 'My::Types::' . $_[0] => 'new' };
37 my Str $x; # $x is now a My::Types::Str object
40 package My::Types::Int;
42 sub TYPEDSCALAR { bless { }, shift }
47 use constant Int => 'My::Types::Int';
49 my Int $y; # $y is now a My::Types::Int object
53 This pragma allows you to hook the execution of typed lexicals declarations (C<my Str $x>) by calling a configurable method in a configurable package at each run.
54 In particular, it can be used to automatically tie or bless typed lexicals whenever they are initialized.
56 Remind that for C<perl> to be able to parse C<my Str $x>, you need :
62 either the C<Str> package to be defined ;
66 or for C<Str> to be a constant sub returning a valid defined package.
70 so make sure you follow one of those two strategies to define your types.
72 This pragma is B<not> implemented with a source filter.
78 XSLoader::load(__PACKAGE__, $VERSION);
83 =head2 C<< import [ as => [ $prefix | $mangler ] ] >>
85 Magically called when writing C<use Lexical::Types>.
86 All the occurences of C<my Str $x> in the current lexical scope will be changed to call at each run a given method in a given package.
87 The method and package are determined by the parameter C<'as'> :
93 If it's left unspecified, the C<TYPEDSCALAR> method in the C<Str> package will be called.
96 my Str $x; # calls Str->TYPEDSCALAR
100 If a plain scalar C<$prefix> is passed as the value, the C<TYPEDSCALAR> method in the C<${prefix}::Str> package will be used.
102 use Lexical::Types as => 'My::'; # or "as => 'My'"
103 my Str $x; # calls My::Str->TYPEDSCALAR
107 If the value given is a code reference C<$mangler>, it will be called at compile-time with arguments C<'Str'> and C<'TYPEDSCALAR'> and is expected to return :
113 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) ;
115 use Lexical::Types as => sub { return $_[0] =~ /Str/ ? @_ : () };
116 my Str $y; # calls Str->TYPEDSCALAR
117 my Int $x; # nothing special
121 or the desired package and method name, in that order (if any of those is C<undef>, the default value will be used instead).
123 use Lexical::Types as => sub { 'My', 'new_' . lc($_[0]) };
124 my Str $x; # the coderef indicates to call My->new_str
128 Note that if the type is a constant, C<$_[0]> will be set to the I<value> of constant and not to its name.
130 use Lexical::Types as => sub { $_[0] => 'new' };
131 use constant Str => 'MyStr';
132 my Str $x; # calls MyStr->new
134 This means in particular that you can't both use constant types and redirect several types to different methods of the same package, because then you can't distinguish between the original types with C<$_[0]>.
146 my $as = delete $args{'as'};
152 $as .= '::' if $as !~ /::$/;
153 $hint = _tag(sub { $as . $_[0] });
155 croak "Invalid $r reference for 'as'";
162 # Yes, we store a coderef inside the hints hash, but that's just for compile
164 $^H{+(__PACKAGE__)} = $hint;
169 Magically called when writing C<no Lexical::Types>.
170 Turns the pragma off.
175 $^H{+(__PACKAGE__)} = undef;
178 =head1 RUN-TIME INITIALIZER METHOD
180 The initializer method receives an alias to the pad slot of the initialized lexical in C<$_[1]> and the original type name in C<$_[2]>.
181 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 the pad slot.
183 use Lexical::Types as => 'My';
189 sub My::Str::TYPEDSCALAR {
190 # $_[1] is an alias to $x, and $_[2] is 'Str'
196 You can integrate L<Lexical::Types> in your module so that using it will provide types to your users without asking them to load either L<Lexical::Types> or the type classes manually.
200 BEGIN { require Lexical::Types; }
203 eval 'package Str; package Int'; # The types you want to support
204 Lexical::Types->import(
205 as => sub { __PACKAGE__, 'new_' . lc($_[0]) }
210 Lexical::Types->unimport;
217 If you prefer to use constants rather than creating empty packages, you can replace the previous example with something like this :
221 BEGIN { require Lexical::Types; }
226 my $type = __PACKAGE__ . '::' . $_;
228 no warnings 'redefine';
229 *{$pkg.'::'.$_} = eval "sub () { '$type' }";
231 Lexical::Types->import(
232 as => sub { $_[0] => 'new' }
237 Lexical::Types->unimport;
240 package MyTypes::Str;
244 package MyTypes::Int;
250 =head2 C<LT_THREADSAFE>
252 True iff the module could have been built when thread-safety features.
256 The restrictions on the type (being either a defined package name or a constant) apply even if you use the C<'as'> option to redirect to another package, and are unlikely to find a workaround as this happens deep inside the lexer - far from the reach of an extension.
258 Only one mangler or prefix can be in use at the same time in a given scope.
262 L<perl> 5.8, L<XSLoader>.
268 L<Attribute::Handlers>.
272 Vincent Pit, C<< <perl at profvince.com> >>, L<http://www.profvince.com>.
274 You can contact me by mail or on C<irc.perl.org> (vincent).
278 Please report any bugs or feature requests to C<bug-lexical-types at rt.cpan.org>, or through the web interface at L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Lexical-Types>. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
282 You can find documentation for this module with the perldoc command.
284 perldoc Lexical::Types
286 Tests code coverage report is available at L<http://www.profvince.com/perl/cover/Lexical-Types>.
288 =head1 ACKNOWLEDGEMENTS
290 Inspired by Ricardo Signes.
292 Thanks Florian Ragwitz for suggesting the use of constants for types.
294 =head1 COPYRIGHT & LICENSE
296 Copyright 2009 Vincent Pit, all rights reserved.
298 This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
302 1; # End of Lexical::Types