]> git.vpit.fr Git - perl/modules/Lexical-Types.git/blob - lib/Lexical/Types.pm
Initial import
[perl/modules/Lexical-Types.git] / lib / Lexical / Types.pm
1 package Lexical::Types;
2
3 use strict;
4 use warnings;
5
6 use Carp qw/croak/;
7
8 =head1 NAME
9
10 Lexical::Types - Extend the semantics of typed lexicals.
11
12 =head1 VERSION
13
14 Version 0.01
15
16 =cut
17
18 our $VERSION;
19 BEGIN {
20  $VERSION = '0.01';
21 }
22
23 =head1 SYNOPSIS
24
25     {
26      package Str;
27
28      sub TYPEDSCALAR { Some::String::Implementation->new }
29     }
30
31     use Lexical::Types;
32
33     my Str $x; # $x is now a Some::String::Implementation object
34
35 =head1 DESCRIPTION
36
37 This module allows you to hook the execution of typed lexicals declarations (C<my Foo $x>).
38 In particular, it can be used to automatically tie or bless typed lexicals.
39
40 It is B<not> implemented with a source filter.
41
42 =cut
43
44 BEGIN {
45  require XSLoader;
46  XSLoader::load(__PACKAGE__, $VERSION);
47 }
48
49 =head1 FUNCTIONS
50
51 =head2 C<< import [ as => [ $prefix | $mangler ] ] >>
52
53 Magically called when writing C<use Lexical::Types>.
54 All the occurences of C<my Foo $x> in the current lexical scope will be changed to call at each run a given method in a given package.
55 The method and package are determined by the parameter C<as> :
56
57 =over 4
58
59 =item *
60
61 If it's left unspecified, the C<TYPEDSCALAR> method in the C<Foo> package will be called.
62
63     use Lexical::Types;
64     my Str $x; # calls Str->TYPEDSCALAR
65
66 =item *
67
68 If a plain scalar C<$prefix> is passed as the value, the C<TYPEDSCALAR> method in the C<${prefix}::Foo> package will be used.
69
70     use Lexical::Types as => 'My::'; # or "as => 'My'"
71     my Str $x; # calls My::Str->TYPEDSCALAR
72
73 =item *
74
75 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).
76 If any of those is C<undef>, the default value will be used instead.
77
78     use Lexical::Types as => sub { 'My', 'new_' . lc($_[0]) };
79     my Str $x; # the coderef indicates to call My->new_str
80
81 =back
82
83 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]>.
84 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>.
85
86 =cut
87
88 sub import {
89  shift;
90  my %args = @_;
91
92  my $hint;
93
94  my $as = delete $args{'as'};
95  if ($as) {
96   my $r = ref $as;
97   if ($r eq 'CODE') {
98    $hint = _tag($as);
99   } elsif (!$r) {
100    $as .= '::' if $as !~ /::$/;
101    $hint = _tag(sub { $as . $_[0] });
102   } else {
103    croak "Invalid $r reference for 'as'";
104   }
105  } else {
106   $hint = _tag(0);
107  }
108
109  $^H |= 0x020000;
110  # Yes, we store a coderef inside the hints hash, but that's just for compile
111  # time.
112  $^H{+(__PACKAGE__)} = $hint;
113 }
114
115 =head2 C<unimport>
116
117 Magically called when writing C<no Lexical::Types>.
118 Turns the module off.
119
120 =cut
121
122 sub unimport {
123  $^H{+(__PACKAGE__)} = undef;
124 }
125
126 =head1 INTEGRATION
127
128 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.
129
130     package MyTypes;
131
132     BEGIN { require Lexical::Types; }
133
134     sub import {
135      eval 'package Str; package Int'; # The types you want to support
136      Lexical::Types->import(
137       as => sub { __PACKAGE__, 'new_' . lc($_[0]) }
138      );
139     }
140
141     sub unimport {
142      Lexical::Types->unimport;
143     }
144
145     sub new_str { ... }
146
147     sub new_int { ... }
148
149 =head1 CAVEATS
150
151 For C<perl> to be able to parse C<my Foo $x>, the package C<Foo> must be defined somewhere, and this even if you use the C<as> option to redirect to another package.
152 It's unlikely to find a workaround, as this happens deep inside the lexer, far from the reach of an extension.
153
154 Only one mangler or prefix can be in use at the same time in a given scope.
155
156 =head1 DEPENDENCIES
157
158 L<perl> 5.8, L<XSLoader>.
159
160 =head1 SEE ALSO
161
162 L<fields>.
163
164 L<Attribute::Handlers>.
165
166 =head1 AUTHOR
167
168 Vincent Pit, C<< <perl at profvince.com> >>, L<http://www.profvince.com>.
169
170 You can contact me by mail or on C<irc.perl.org> (vincent).
171
172 =head1 BUGS
173
174 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.
175
176 =head1 SUPPORT
177
178 You can find documentation for this module with the perldoc command.
179
180     perldoc Lexical::Types
181
182 =head1 ACKNOWLEDGEMENTS
183
184 Inspired by Ricardo Signes.
185
186 =head1 COPYRIGHT & LICENSE
187
188 Copyright 2009 Vincent Pit, all rights reserved.
189
190 This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
191
192 =cut
193
194 1; # End of Lexical::Types