Codebase list libmoose-perl / ebfe7a8
[svn-upgrade] Integrating new upstream version, libmoose-perl (0.51) Krzysztof Krzyzaniak 15 years ago
46 changed file(s) with 406 addition(s) and 236 deletion(s). Raw diff Collapse all Expand all
00 Revision history for Perl extension Moose
1
2 0.51 Thurs. Jun 26, 2008
3 * Moose::Role
4 - add unimport so "no Moose::Role" actually does
5 something (sartak)
6
7 * Moose::Meta::Role::Application::ToRole
8 - when RoleA did RoleB, and RoleA aliased a method from RoleB in
9 order to provide its own implementation, that method still got
10 added to the list of required methods for consumers of
11 RoleB. Now an aliased method is only added to the list of
12 required methods if the role doing the aliasing does not
13 provide its own implementation. See Recipe 11 for an example
14 of all this. (Dave Rolsky)
15 - added tests for this
16
17 * Moose::Meta::Method::Constructor
18 - when a single argument that wasn't a hashref was provided to
19 an immutabilized constructor, the error message was very
20 unhelpful, as opposed to the non-immutable error. Reported by
21 dew. (Dave Rolsky)
22 - added test for this (Dave Rolsky)
23
24 * Moose::Meta::Attribute
25 - added support for meta_attr->does("ShortAlias") (sartak)
26 - added tests for this (sartak)
27 - moved the bulk of the `handles` handling to the new
28 install_delegation method (Stevan)
29
30 * Moose::Object
31 - Added BUILDARGS, a new step in new()
32
33 * Moose::Meta::Role::Application::RoleSummation
34 - fix typos no one ever sees (sartak)
35
36 * Moose::Util::TypeConstraints
37 * Moose::Meta::TypeConstraint
38 * Moose::Meta::TypeCoercion
39 - Attempt to work around the ??{ } vs. threads issue
40 - Some null_constraint optimizations
141
242 0.50 Thurs. Jun 11, 2008
343 - Fixed a version number issue by bumping all modules
0 ---
1 abstract: A postmodern object system for Perl 5
2 author:
3 - Stevan Little <stevan@iinteractive.com>
4 build_requires:
0 ---
1 abstract: 'A postmodern object system for Perl 5'
2 author:
3 - 'Stevan Little <stevan@iinteractive.com>'
4 build_requires:
55 Test::Exception: 0.21
66 Test::LongString: 0
77 Test::More: 0.62
88 distribution_type: module
9 generated_by: Module::Install version 0.68
9 generated_by: 'Module::Install version 0.75'
1010 license: perl
11 meta-spec:
11 meta-spec:
1212 url: http://module-build.sourceforge.net/META-spec-v1.3.html
1313 version: 1.3
1414 name: Moose
15 no_index:
16 directory:
15 no_index:
16 directory:
1717 - inc
1818 - t
19 requires:
19 requires:
2020 Carp: 0
21 Class::MOP: 0.56
21 Class::MOP: 0.59
2222 Filter::Simple: 0
2323 Scalar::Util: 1.18
2424 Sub::Exporter: 0.972
25 tests: t/*.t t/000_recipes/*.t t/010_basics/*.t t/020_attributes/*.t t/030_roles/*.t t/040_type_constraints/*.t t/050_metaclasses/*.t t/060_compat/*.t t/100_bugs/*.t t/200_examples/*.t t/300_immutable/*.t t/400_moose_util/*.t t/500_test_moose/*.t
26 version: 0.45
25 version: 0.51
00 use strict;
11 use warnings;
2 use inc::Module::Install;
2 use inc::Module::Install 0.75;
33
44 name 'Moose';
55 all_from 'lib/Moose.pm';
0 Moose version 0.50
0 Moose version 0.51
11 ===========================
22
33 See the individual module documentation for more information
7777 If you need to affect the constructor's parameters prior to the
7878 instance actually being constructed, you have a number of options.
7979
80 First, there are I<coercions> (See the L<Moose::Cookbook::Recipe5>
81 for a complete example and explaination of coercions). With
82 coercions it is possible to morph argument values into the correct
83 expected types. This approach is the most flexible and robust, but
84 does have a slightly higher learning curve.
85
86 Second, using an C<around> method modifier on C<new> can be an
87 effective way to affect the contents of C<@_> prior to letting
88 Moose deal with it. This carries with it the extra burden for
89 your subclasses, in that they have to be sure to explicitly
90 call your C<new> and/or work around your C<new> to get to the
91 version from L<Moose::Object>.
92
93 The last approach is to use the standard Perl technique of calling
94 the C<SUPER::new> within your own custom version of C<new>. This,
95 of course, brings with it all the issues of the C<around> solution
96 as well as any issues C<SUPER::> might add.
97
98 In short, try to use C<BUILD> and coercions, they are your best
99 bets.
80 To change the parameter processing as a whole, you can use
81 the C<BUILDARGS> method. The default implementation accepts key/value
82 pairs or a hash reference. You can override it to take positional args,
83 or any other format
84
85 To change the handling of individual parameters, there are I<coercions>
86 (See the L<Moose::Cookbook::Recipe5> for a complete example and
87 explaination of coercions). With coercions it is possible to morph
88 argument values into the correct expected types. This approach is the
89 most flexible and robust, but does have a slightly higher learning
90 curve.
10091
10192 =head3 How do I make non-Moose constructors work with Moose?
10293
103 Moose provides its own constructor, but it does it by making all
104 Moose-based classes inherit from L<Moose::Object>. When inheriting
105 from a non-Moose class, the inheritance chain to L<Moose::Object>
106 is broken. The simplest way to fix this is to simply explicitly
107 inherit from L<Moose::Object> yourself. However, this does not
108 always fix the issue of a constructor. Here is a basic example of
109 how this can be worked around:
94 Usually the correct approach to subclassing a non Moose class is
95 delegation. Moose makes this easy using the C<handles> keyword,
96 coercions, and C<lazy_build>, so subclassing is often not the
97 ideal route.
98
99 That said, the default Moose constructors is inherited from
100 L<Moose::Object>. When inheriting from a non-Moose class, the
101 inheritance chain to L<Moose::Object> is broken. The simplest way
102 to fix this is to simply explicitly inherit from L<Moose::Object>
103 yourself.
104
105 However, this does not always fix the issue of actually calling the Moose
106 constructor. Fortunately L<Class::MOP::Class/new_object>, the low level
107 constructor, accepts the special C<__INSTANCE__> parameter, allowing you to
108 instantiate your Moose attributes:
110109
111110 package My::HTML::Template;
112111 use Moose;
122121 return $class->meta->new_object(
123122 # pass in the constructed object
124123 # using the special key __INSTANCE__
125 __INSTANCE__ => $obj, @_
124 __INSTANCE__ => $obj,
125 @_, # pass in the normal args
126126 );
127127 }
128128
129129 Of course, this only works if both your Moose class and the
130130 inherited non-Moose class use the same instance type (typically
131 HASH refs).
131 HASH refs).
132
133 Note that this doesn't call C<BUILDALL> automatically, you must do that
134 yourself.
132135
133136 Other techniques can be used as well, such as creating the object
134137 using C<Moose::Object::new>, but calling the inherited non-Moose
291294 This library is free software; you can redistribute it and/or modify
292295 it under the same terms as Perl itself.
293296
294 =cut
297 =cut
1111
1212 has 'is_paused' => (
1313 is => 'rw',
14 isa => 'Boo',
14 isa => 'Bool',
1515 default => 0,
1616 );
1717
77 use Carp 'confess';
88 use overload ();
99
10 our $VERSION = '0.50';
10 our $VERSION = '0.51';
1111 our $AUTHORITY = 'cpan:STEVAN';
1212
1313 use Moose::Meta::Method::Accessor;
5050 predicate => 'has_applied_traits',
5151 ));
5252
53 # NOTE:
5453 # we need to have a ->does method in here to
5554 # more easily support traits, and the introspection
56 # of those traits. So in order to do this we
57 # just alias Moose::Object's version of it.
58 # - SL
59 *does = \&Moose::Object::does;
55 # of those traits. We extend the does check to look
56 # for metatrait aliases.
57 sub does {
58 my ($self, $role_name) = @_;
59 my $name = eval {
60 Moose::Util::resolve_metatrait_alias(Attribute => $role_name)
61 };
62 return 0 if !defined($name); # failed to load class
63 return Moose::Object::does($self, $name);
64 }
6065
6166 sub new {
6267 my ($class, $name, %options) = @_;
207212
208213 if (exists $options->{is}) {
209214
210 =pod
211
212 is => ro, writer => _foo # turns into (reader => foo, writer => _foo) as before
213 is => rw, writer => _foo # turns into (reader => foo, writer => _foo)
214 is => rw, accessor => _foo # turns into (accessor => _foo)
215 is => ro, accessor => _foo # error, accesor is rw
216
217 =cut
215 ### -------------------------
216 ## is => ro, writer => _foo # turns into (reader => foo, writer => _foo) as before
217 ## is => rw, writer => _foo # turns into (reader => foo, writer => _foo)
218 ## is => rw, accessor => _foo # turns into (accessor => _foo)
219 ## is => ro, accessor => _foo # error, accesor is rw
220 ### -------------------------
218221
219222 if ($options->{is} eq 'ro') {
220223 confess "Cannot define an accessor name on a read-only attribute, accessors are read/write"
502505 sub install_accessors {
503506 my $self = shift;
504507 $self->SUPER::install_accessors(@_);
505
506 if ($self->has_handles) {
508 $self->install_delegation if $self->has_handles;
509 return;
510 }
511
512 sub install_delegation {
513 my $self = shift;
514
515 # NOTE:
516 # Here we canonicalize the 'handles' option
517 # this will sort out any details and always
518 # return an hash of methods which we want
519 # to delagate to, see that method for details
520 my %handles = $self->_canonicalize_handles();
521
522 # find the accessor method for this attribute
523 my $accessor = $self->get_read_method_ref;
524 # then unpack it if we need too ...
525 $accessor = $accessor->body if blessed $accessor;
526
527 # install the delegation ...
528 my $associated_class = $self->associated_class;
529 foreach my $handle (keys %handles) {
530 my $method_to_call = $handles{$handle};
531 my $class_name = $associated_class->name;
532 my $name = "${class_name}::${handle}";
533
534 (!$associated_class->has_method($handle))
535 || confess "You cannot overwrite a locally defined method ($handle) with a delegation";
507536
508537 # NOTE:
509 # Here we canonicalize the 'handles' option
510 # this will sort out any details and always
511 # return an hash of methods which we want
512 # to delagate to, see that method for details
513 my %handles = $self->_canonicalize_handles();
514
515 # find the accessor method for this attribute
516 my $accessor = $self->get_read_method_ref;
517 # then unpack it if we need too ...
518 $accessor = $accessor->body if blessed $accessor;
519
520 # install the delegation ...
521 my $associated_class = $self->associated_class;
522 foreach my $handle (keys %handles) {
523 my $method_to_call = $handles{$handle};
524 my $class_name = $associated_class->name;
525 my $name = "${class_name}::${handle}";
526
527 (!$associated_class->has_method($handle))
528 || confess "You cannot overwrite a locally defined method ($handle) with a delegation";
529
538 # handles is not allowed to delegate
539 # any of these methods, as they will
540 # override the ones in your class, which
541 # is almost certainly not what you want.
542
543 # FIXME warn when $handle was explicitly specified, but not if the source is a regex or something
544 #cluck("Not delegating method '$handle' because it is a core method") and
545 next if $class_name->isa("Moose::Object") and $handle =~ /^BUILD|DEMOLISH$/ || Moose::Object->can($handle);
546
547 if ('CODE' eq ref($method_to_call)) {
548 $associated_class->add_method($handle => Class::MOP::subname($name, $method_to_call));
549 }
550 else {
530551 # NOTE:
531 # handles is not allowed to delegate
532 # any of these methods, as they will
533 # override the ones in your class, which
534 # is almost certainly not what you want.
535
536 # FIXME warn when $handle was explicitly specified, but not if the source is a regex or something
537 #cluck("Not delegating method '$handle' because it is a core method") and
538 next if $class_name->isa("Moose::Object") and $handle =~ /^BUILD|DEMOLISH$/ || Moose::Object->can($handle);
539
540 if ('CODE' eq ref($method_to_call)) {
541 $associated_class->add_method($handle => Class::MOP::subname($name, $method_to_call));
542 }
543 else {
544 # NOTE:
545 # we used to do a goto here, but the
546 # goto didn't handle failure correctly
547 # (it just returned nothing), so I took
548 # that out. However, the more I thought
549 # about it, the less I liked it doing
550 # the goto, and I prefered the act of
551 # delegation being actually represented
552 # in the stack trace.
553 # - SL
554 $associated_class->add_method($handle => Class::MOP::subname($name, sub {
555 my $proxy = (shift)->$accessor();
556 (defined $proxy)
557 || confess "Cannot delegate $handle to $method_to_call because " .
558 "the value of " . $self->name . " is not defined";
559 $proxy->$method_to_call(@_);
560 }));
561 }
562 }
563 }
564
565 return;
552 # we used to do a goto here, but the
553 # goto didn't handle failure correctly
554 # (it just returned nothing), so I took
555 # that out. However, the more I thought
556 # about it, the less I liked it doing
557 # the goto, and I prefered the act of
558 # delegation being actually represented
559 # in the stack trace.
560 # - SL
561 $associated_class->add_method($handle => Class::MOP::subname($name, sub {
562 my $proxy = (shift)->$accessor();
563 (defined $proxy)
564 || confess "Cannot delegate $handle to $method_to_call because " .
565 "the value of " . $self->name . " is not defined";
566 $proxy->$method_to_call(@_);
567 }));
568 }
569 }
566570 }
567571
568572 # private methods to help delegation ...
687691
688692 =item B<install_accessors>
689693
694 =item B<install_delegation>
695
690696 =item B<accessor_metaclass>
691697
692698 =item B<get_value>
88 use Carp 'confess';
99 use Scalar::Util 'weaken', 'blessed';
1010
11 our $VERSION = '0.50';
11 our $VERSION = '0.51';
1212 our $AUTHORITY = 'cpan:STEVAN';
1313
1414 use Moose::Meta::Method::Overriden;
33 use strict;
44 use warnings;
55
6 our $VERSION = '0.50';
6 our $VERSION = '0.51';
77 our $AUTHORITY = 'cpan:STEVAN';
88
99 use base "Class::MOP::Instance";
55
66 use Carp 'confess';
77
8 our $VERSION = '0.50';
8 our $VERSION = '0.51';
99 our $AUTHORITY = 'cpan:STEVAN';
1010
1111 use base 'Moose::Meta::Method',
44
55 use Carp 'confess';
66
7 our $VERSION = '0.50';
7 our $VERSION = '0.51';
88 our $AUTHORITY = 'cpan:STEVAN';
99
1010 use base 'Moose::Meta::Method';
66 use Carp 'confess';
77 use Scalar::Util 'blessed', 'weaken', 'looks_like_number';
88
9 our $VERSION = '0.50';
9 our $VERSION = '0.51';
1010 our $AUTHORITY = 'cpan:STEVAN';
1111
1212 use base 'Moose::Meta::Method',
7474 $source .= "\n" . 'return $class->Moose::Object::new(@_)';
7575 $source .= "\n" . ' if $class ne \'' . $self->associated_metaclass->name . '\';';
7676
77 $source .= "\n" . 'my %params = (scalar @_ == 1) ? %{$_[0]} : @_;';
78
79 $source .= "\n" . 'my $instance = ' . $self->meta_instance->inline_create_instance('$class');
77 $source .= "\n" . 'my $params = ' . $self->_generate_BUILDARGS('$class', '@_');
78
79 $source .= ";\n" . 'my $instance = ' . $self->meta_instance->inline_create_instance('$class');
8080
8181 $source .= ";\n" . (join ";\n" => map {
8282 $self->_generate_slot_initializer($_)
119119 $self->{'&!body'} = $code;
120120 }
121121
122 sub _generate_BUILDARGS {
123 my ( $self, $class, $args ) = @_;
124
125 my $buildargs = $self->associated_metaclass->find_method_by_name("BUILDARGS");
126
127 if ( $args eq '@_' and ( !$buildargs or $buildargs->body == \&Moose::Object::BUILDARGS ) ) {
128 return join("\n",
129 'do {',
130 'no warnings "uninitialized";',
131 'confess "Single parameters to new() must be a HASH ref"',
132 ' if scalar @_ == 1 && defined $_[0] && ref($_[0]) ne q{HASH};',
133 '(scalar @_ == 1) ? {%{$_[0]}} : {@_};',
134 '}',
135 );
136 } else {
137 return $class . "->BUILDARGS($args)";
138 }
139 }
140
122141 sub _generate_BUILDALL {
123142 my $self = shift;
124143 my @BUILD_calls;
125144 foreach my $method (reverse $self->associated_metaclass->find_all_methods_by_name('BUILD')) {
126 push @BUILD_calls => '$instance->' . $method->{class} . '::BUILD(\%params)';
145 push @BUILD_calls => '$instance->' . $method->{class} . '::BUILD($params)';
127146 }
128147 return join ";\n" => @BUILD_calls;
129148 }
136155 if ($attr->can('has_trigger') && $attr->has_trigger) {
137156 if (defined(my $init_arg = $attr->init_arg)) {
138157 push @trigger_calls => (
139 '(exists $params{\'' . $init_arg . '\'}) && do {' . "\n "
158 '(exists $params->{\'' . $init_arg . '\'}) && do {' . "\n "
140159 . '$attrs->[' . $i . ']->trigger->('
141160 . '$instance, '
142161 . $self->meta_instance->inline_get_slot_value(
165184 my $is_moose = $attr->isa('Moose::Meta::Attribute'); # XXX FIXME
166185
167186 if ($is_moose && defined($attr->init_arg) && $attr->is_required && !$attr->has_default && !$attr->has_builder) {
168 push @source => ('(exists $params{\'' . $attr->init_arg . '\'}) ' .
187 push @source => ('(exists $params->{\'' . $attr->init_arg . '\'}) ' .
169188 '|| confess "Attribute (' . $attr->name . ') is required";');
170189 }
171190
172191 if (($attr->has_default || $attr->has_builder) && !($is_moose && $attr->is_lazy)) {
173192
174193 if ( defined( my $init_arg = $attr->init_arg ) ) {
175 push @source => 'if (exists $params{\'' . $init_arg . '\'}) {';
176
177 push @source => ('my $val = $params{\'' . $init_arg . '\'};');
194 push @source => 'if (exists $params->{\'' . $init_arg . '\'}) {';
195
196 push @source => ('my $val = $params->{\'' . $init_arg . '\'};');
178197
179198 if ($is_moose && $attr->has_type_constraint) {
180199 if ($attr->should_coerce && $attr->type_constraint->has_coercion) {
220239 push @source => "}" if defined $attr->init_arg;
221240 }
222241 elsif ( defined( my $init_arg = $attr->init_arg ) ) {
223 push @source => '(exists $params{\'' . $init_arg . '\'}) && do {';
224
225 push @source => ('my $val = $params{\'' . $init_arg . '\'};');
242 push @source => '(exists $params->{\'' . $init_arg . '\'}) && do {';
243
244 push @source => ('my $val = $params->{\'' . $init_arg . '\'};');
226245 if ($is_moose && $attr->has_type_constraint) {
227246 if ($attr->should_coerce && $attr->type_constraint->has_coercion) {
228247 push @source => $self->_generate_type_coercion(
66 use Carp 'confess';
77 use Scalar::Util 'blessed', 'weaken';
88
9 our $VERSION = '0.50';
9 our $VERSION = '0.51';
1010 our $AUTHORITY = 'cpan:STEVAN';
1111
1212 use base 'Moose::Meta::Method',
44
55 use Carp 'confess';
66
7 our $VERSION = '0.50';
7 our $VERSION = '0.51';
88 our $AUTHORITY = 'cpan:STEVAN';
99
1010 use base 'Moose::Meta::Method';
22 use strict;
33 use warnings;
44
5 our $VERSION = '0.50';
5 our $VERSION = '0.51';
66 our $AUTHORITY = 'cpan:STEVAN';
77
88 use base 'Class::MOP::Method';
4242 This library is free software; you can redistribute it and/or modify
4343 it under the same terms as Perl itself.
4444
45 =cut
45 =cut
99
1010 use Moose::Meta::Role::Composite;
1111
12 our $VERSION = '0.50';
12 our $VERSION = '0.51';
1313 our $AUTHORITY = 'cpan:STEVAN';
1414
1515 use base 'Moose::Meta::Role::Application';
118118 my %seen;
119119 foreach my $attr (@all_attributes) {
120120 if (exists $seen{$attr->{name}}) {
121 confess "We have encountered an attribute conflict with '" . $attr->{name} . "'"
121 confess "We have encountered an attribute conflict with '" . $attr->{name} . "' "
122122 . "during composition. This is fatal error and cannot be disambiguated."
123123 if $seen{$attr->{name}} != $attr->{attr};
124124 }
88
99 use Data::Dumper;
1010
11 our $VERSION = '0.50';
11 our $VERSION = '0.51';
1212 our $AUTHORITY = 'cpan:STEVAN';
1313
1414 use base 'Moose::Meta::Role::Application';
66 use Carp 'confess';
77 use Scalar::Util 'blessed';
88
9 our $VERSION = '0.50';
9 our $VERSION = '0.51';
1010 our $AUTHORITY = 'cpan:STEVAN';
1111
1212 use base 'Moose::Meta::Role::Application::ToClass';
88
99 use Data::Dumper;
1010
11 our $VERSION = '0.50';
11 our $VERSION = '0.51';
1212 our $AUTHORITY = 'cpan:STEVAN';
1313
1414 use base 'Moose::Meta::Role::Application';
6969 foreach my $method_name ($role1->get_method_list) {
7070
7171 next if $self->is_method_excluded($method_name);
72
73 if ($self->is_method_aliased($method_name)) {
74 my $aliased_method_name = $self->get_method_aliases->{$method_name};
75 # it if it has one already
76 if ($role2->has_method($aliased_method_name) &&
77 # and if they are not the same thing ...
78 $role2->get_method($aliased_method_name)->body != $role1->get_method($method_name)->body) {
79 confess "Cannot create a method alias if a local method of the same name exists";
80 }
81
82 $role2->alias_method(
83 $aliased_method_name,
84 $role1->get_method($method_name)
85 );
86
87 if (!$role2->has_method($method_name)) {
88 $role2->add_required_methods($method_name);
89 }
90
91 next;
92 }
7293
7394 # it if it has one already
7495 if ($role2->has_method($method_name) &&
87108
88109 }
89110
90 if ($self->is_method_aliased($method_name)) {
91 my $aliased_method_name = $self->get_method_aliases->{$method_name};
92 # it if it has one already
93 if ($role2->has_method($aliased_method_name) &&
94 # and if they are not the same thing ...
95 $role2->get_method($aliased_method_name)->body != $role1->get_method($method_name)->body) {
96 confess "Cannot create a method alias if a local method of the same name exists";
97 }
98 $role2->alias_method(
99 $aliased_method_name,
100 $role1->get_method($method_name)
101 );
102 }
103111 }
104112 }
105113
33 use warnings;
44 use metaclass;
55
6 our $VERSION = '0.50';
6 our $VERSION = '0.51';
77 our $AUTHORITY = 'cpan:STEVAN';
88
99 __PACKAGE__->meta->add_attribute('method_exclusions' => (
66 use Carp 'confess';
77 use Scalar::Util 'blessed';
88
9 our $VERSION = '0.50';
9 our $VERSION = '0.51';
1010 our $AUTHORITY = 'cpan:STEVAN';
1111
1212 use base 'Moose::Meta::Role';
109109 This library is free software; you can redistribute it and/or modify
110110 it under the same terms as Perl itself.
111111
112 =cut
112 =cut
33 use strict;
44 use warnings;
55
6 our $VERSION = '0.50';
6 our $VERSION = '0.51';
77 our $AUTHORITY = 'cpan:STEVAN';
88
99 use base 'Moose::Meta::Role::Method';
3939 This library is free software; you can redistribute it and/or modify
4040 it under the same terms as Perl itself.
4141
42 =cut
42 =cut
33 use strict;
44 use warnings;
55
6 our $VERSION = '0.50';
6 our $VERSION = '0.51';
77 our $AUTHORITY = 'cpan:STEVAN';
88
99 use base 'Class::MOP::Method';
4343 This library is free software; you can redistribute it and/or modify
4444 it under the same terms as Perl itself.
4545
46 =cut
46 =cut
77 use Carp 'confess';
88 use Scalar::Util 'blessed';
99
10 our $VERSION = '0.50';
10 our $VERSION = '0.51';
1111 our $AUTHORITY = 'cpan:STEVAN';
1212
1313 use Moose::Meta::Class;
77 use Carp 'confess';
88 use Scalar::Util 'blessed';
99
10 our $VERSION = '0.50';
10 our $VERSION = '0.51';
1111 our $AUTHORITY = 'cpan:STEVAN';
1212
1313 use base 'Moose::Meta::TypeCoercion';
9999 This library is free software; you can redistribute it and/or modify
100100 it under the same terms as Perl itself.
101101
102 =cut
102 =cut
99 use Moose::Meta::Attribute;
1010 use Moose::Util::TypeConstraints ();
1111
12 our $VERSION = '0.50';
12 our $VERSION = '0.51';
1313 our $AUTHORITY = 'cpan:STEVAN';
1414
1515 __PACKAGE__->meta->add_attribute('type_coercion_map' => (
66 use Scalar::Util 'blessed';
77 use Moose::Util::TypeConstraints ();
88
9 our $VERSION = '0.50';
9 our $VERSION = '0.51';
1010 our $AUTHORITY = 'cpan:STEVAN';
1111
1212 use base 'Moose::Meta::TypeConstraint';
55
66 use Moose::Util::TypeConstraints ();
77
8 our $VERSION = '0.50';
8 our $VERSION = '0.51';
99 our $AUTHORITY = 'cpan:STEVAN';
1010
1111 use base 'Moose::Meta::TypeConstraint';
33 use warnings;
44 use metaclass;
55
6 our $VERSION = '0.50';
6 our $VERSION = '0.51';
77 our $AUTHORITY = 'cpan:STEVAN';
88
99 use base 'Moose::Meta::TypeConstraint';
77 use Carp 'confess';
88 use Moose::Util::TypeConstraints;
99
10 our $VERSION = '0.50';
10 our $VERSION = '0.51';
1111 our $AUTHORITY = 'cpan:STEVAN';
1212
1313 use base 'Moose::Meta::TypeConstraint';
77 use Scalar::Util 'blessed';
88 use Carp 'confess';
99
10 our $VERSION = '0.50';
10 our $VERSION = '0.51';
1111 our $AUTHORITY = 'cpan:STEVAN';
1212
1313 use base 'Class::MOP::Object';
66 use Scalar::Util 'blessed';
77 use Moose::Util::TypeConstraints ();
88
9 our $VERSION = '0.50';
9 our $VERSION = '0.51';
1010 our $AUTHORITY = 'cpan:STEVAN';
1111
1212 use base 'Moose::Meta::TypeConstraint';
66
77 use Moose::Meta::TypeCoercion::Union;
88
9 our $VERSION = '0.50';
9 our $VERSION = '0.51';
1010 our $AUTHORITY = 'cpan:STEVAN';
1111
1212 use base 'Moose::Meta::TypeConstraint';
1010 use Carp 'confess';
1111 use Scalar::Util qw(blessed refaddr);
1212
13 our $VERSION = '0.50';
13 our $VERSION = '0.51';
1414 our $AUTHORITY = 'cpan:STEVAN';
1515
1616 __PACKAGE__->meta->add_attribute('name' => (reader => 'name'));
1818 reader => 'parent',
1919 predicate => 'has_parent',
2020 ));
21
22 my $null_constraint = sub { 1 };
2123 __PACKAGE__->meta->add_attribute('constraint' => (
2224 reader => 'constraint',
2325 writer => '_set_constraint',
24 default => sub { sub { 1 } }
26 default => sub { $null_constraint }
2527 ));
2628 __PACKAGE__->meta->add_attribute('message' => (
2729 accessor => 'message',
172174 sub _compile_subtype {
173175 my ($self, $check) = @_;
174176
175 # so we gather all the parents in order
176 # and grab their constraints ...
177 # gather all the parent constraintss in order
177178 my @parents;
179 my $optimized_parent;
178180 foreach my $parent ($self->_collect_all_parents) {
181 # if a parent is optimized, the optimized constraint already includes
182 # all of its parents tcs, so we can break the loop
179183 if ($parent->has_hand_optimized_type_constraint) {
180 unshift @parents => $parent->hand_optimized_type_constraint;
184 push @parents => $optimized_parent = $parent->hand_optimized_type_constraint;
181185 last;
182186 }
183187 else {
184 unshift @parents => $parent->constraint;
188 push @parents => $parent->constraint;
185189 }
186190 }
187191
188 # then we compile them to run without
189 # having to recurse as we did before
192 @parents = grep { $_ != $null_constraint } reverse @parents;
193
194 unless ( @parents ) {
195 return $self->_compile_type($check);
196 } elsif( $optimized_parent and @parents == 1 ) {
197 # the case of just one optimized parent is optimized to prevent
198 # looping and the unnecessary localization
199 if ( $check == $null_constraint ) {
200 return $optimized_parent;
201 } else {
202 return Class::MOP::subname($self->name, sub {
203 return undef unless $optimized_parent->($_[0]);
204 local $_ = $_[0];
205 $check->($_[0]);
206 });
207 }
208 } else {
209 # general case, check all the constraints, from the first parent to ourselves
210 my @checks = @parents;
211 push @checks, $check if $check != $null_constraint;
212 return Class::MOP::subname($self->name => sub {
213 local $_ = $_[0];
214 foreach my $check (@checks) {
215 return undef unless $check->($_[0]);
216 }
217 return 1;
218 });
219 }
220 }
221
222 sub _compile_type {
223 my ($self, $check) = @_;
224
225 return $check if $check == $null_constraint; # Item, Any
226
190227 return Class::MOP::subname($self->name => sub {
191228 local $_ = $_[0];
192 foreach my $parent (@parents) {
193 return undef unless $parent->($_[0]);
194 }
195 return undef unless $check->($_[0]);
196 1;
197 });
198 }
199
200 sub _compile_type {
201 my ($self, $check) = @_;
202 return Class::MOP::subname($self->name => sub {
203 local $_ = $_[0];
204 return undef unless $check->($_[0]);
205 1;
229 $check->($_[0]);
206230 });
207231 }
208232
88
99 use Carp 'confess';
1010
11 our $VERSION = '0.50';
11 our $VERSION = '0.51';
1212 our $AUTHORITY = 'cpan:STEVAN';
1313
1414 sub new {
1515 my $class = shift;
16 my %params;
16 my $params = $class->BUILDARGS(@_);
17 my $self = $class->meta->new_object(%$params);
18 $self->BUILDALL($params);
19 return $self;
20 }
21
22 sub BUILDARGS {
23 my $class = shift;
24
1725 if (scalar @_ == 1) {
1826 if (defined $_[0]) {
27 no warnings 'uninitialized';
1928 (ref($_[0]) eq 'HASH')
2029 || confess "Single parameters to new() must be a HASH ref";
21 %params = %{$_[0]};
30 return {%{$_[0]}};
31 } else {
32 return {}; # FIXME this is compat behavior, but is it correct?
2233 }
34 } else {
35 return {@_};
2336 }
24 else {
25 %params = @_;
26 }
27 my $self = $class->meta->new_object(%params);
28 $self->BUILDALL(\%params);
29 return $self;
3037 }
3138
3239 sub BUILDALL {
7077 sub does {
7178 my ($self, $role_name) = @_;
7279 (defined $role_name)
73 || confess "You much supply a role name to does()";
80 || confess "You must supply a role name to does()";
7481 my $meta = $self->meta;
7582 foreach my $class ($meta->class_precedence_list) {
7683 my $m = $meta->initialize($class);
127134
128135 =item B<new>
129136
130 This will create a new instance and call C<BUILDALL>.
137 This will call C<BUILDARGS>, create a new instance and call C<BUILDALL>.
138
139 =item B<BUILDARGS>
140
141 This method processes an argument list into a hash reference. It is used by
142 C<new>.
131143
132144 =item B<BUILDALL>
133145
99 use Data::OptList;
1010 use Sub::Exporter;
1111
12 our $VERSION = '0.50';
12 our $VERSION = '0.51';
1313 our $AUTHORITY = 'cpan:STEVAN';
1414
1515 use Moose ();
4848 extends => sub {
4949 my $meta = _find_meta();
5050 return Class::MOP::subname('Moose::Role::extends' => sub {
51 croak "Moose::Role does not currently support 'extends'"
51 croak "Roles do not currently support 'extends'"
5252 });
5353 },
5454 with => sub {
181181 goto $exporter;
182182 };
183183
184 sub unimport {
185 no strict 'refs';
186 my $class = Moose::_get_caller(@_);
187
188 # loop through the exports ...
189 foreach my $name ( keys %exports ) {
190
191 # if we find one ...
192 if ( defined &{ $class . '::' . $name } ) {
193 my $keyword = \&{ $class . '::' . $name };
194
195 # make sure it is from Moose::Role
196 my ($pkg_name) = Class::MOP::get_code_info($keyword);
197 next if $pkg_name ne 'Moose::Role';
198
199 # and if it is from Moose::Role then undef the slot
200 delete ${ $class . '::' }{$name};
201 }
202 }
203 }
184204 }
185205
186206 1;
249269 lightly.
250270
251271 =back
272
273 =head2 B<unimport>
274
275 Moose::Role offers a way to remove the keywords it exports, through the
276 C<unimport> method. You simply have to say C<no Moose::Role> at the bottom of
277 your code for this to work.
252278
253279 =head1 CAVEATS
254280
44
55 use Scalar::Util 'blessed', 'looks_like_number';
66
7 our $VERSION = '0.50';
7 our $VERSION = '0.51';
88 our $AUTHORITY = 'cpan:STEVAN';
99
1010 sub Value { defined($_[0]) && !ref($_[0]) }
77 use Scalar::Util 'blessed';
88 use Sub::Exporter;
99
10 our $VERSION = '0.50';
10 our $VERSION = '0.51';
1111 our $AUTHORITY = 'cpan:STEVAN';
1212
1313 ## --------------------------------------------------------
107107 no strict 'refs';
108108 foreach my $constraint (keys %{$REGISTRY->type_constraints}) {
109109 my $tc = $REGISTRY->get_type_constraint($constraint)->_compiled_type_constraint;
110 *{"${pkg}::${constraint}"} = sub { $tc->($_[0]) ? 1 : undef };
110 *{"${pkg}::${constraint}"} = sub { $tc->($_[0]) ? 1 : undef }; # the undef is for compat
111111 }
112112 }
113113
454454 my $valid_chars = qr{[\w:]};
455455 my $type_atom = qr{ $valid_chars+ };
456456
457 my $any;
458
457459 my $type = qr{ $valid_chars+ (?: \[ (??{$any}) \] )? }x;
458460 my $type_capture_parts = qr{ ($valid_chars+) (?: \[ ((??{$any})) \] )? }x;
459461 my $type_with_parameter = qr{ $valid_chars+ \[ (??{$any}) \] }x;
461463 my $op_union = qr{ \s* \| \s* }x;
462464 my $union = qr{ $type (?: $op_union $type )+ }x;
463465
464 our $any = qr{ $type | $union }x;
466 $any = qr{ $type | $union }x;
465467
466468 sub _parse_parameterized_type_constraint {
469 { no warnings 'void'; $any; } # force capture of interpolated lexical
467470 $_[0] =~ m{ $type_capture_parts }x;
468471 return ($1, $2);
469472 }
470473
471474 sub _detect_parameterized_type_constraint {
475 { no warnings 'void'; $any; } # force capture of interpolated lexical
472476 $_[0] =~ m{ ^ $type_with_parameter $ }x;
473477 }
474478
475479 sub _parse_type_constraint_union {
480 { no warnings 'void'; $any; } # force capture of interpolated lexical
476481 my $given = shift;
477482 my @rv;
478483 while ( $given =~ m{ \G (?: $op_union )? ($type) }gcx ) {
488493 }
489494
490495 sub _detect_type_constraint_union {
496 { no warnings 'void'; $any; } # force capture of interpolated lexical
491497 $_[0] =~ m{^ $type $op_union $type ( $op_union .* )? $}x;
492498 }
493499 }
77 use Carp 'confess';
88 use Class::MOP 0.56;
99
10 our $VERSION = '0.50';
10 our $VERSION = '0.51';
1111 our $AUTHORITY = 'cpan:STEVAN';
1212
1313 my @exports = qw[
33 use strict;
44 use warnings;
55
6 our $VERSION = '0.50';
6 our $VERSION = '0.51';
77 our $AUTHORITY = 'cpan:STEVAN';
88
99 use Scalar::Util 'blessed';
77
88 use Moose::Util 'does_role', 'find_meta';
99
10 our $VERSION = '0.50';
10 our $VERSION = '0.51';
1111 our $AUTHORITY = 'cpan:STEVAN';
1212
1313 my @exports = qw[
44
55 use Class::MOP;
66
7 our $VERSION = '0.50';
7 our $VERSION = '0.51';
88 our $AUTHORITY = 'cpan:STEVAN';
99
1010 BEGIN {
00 use strict;
11 use warnings;
2 use Test::More skip_all => 'not working yet';
2 use Test::More tests => 5;
33 use Class::MOP;
44
5 # follow is original code
5 # This is copied directly from recipe 11
66 {
77 package Restartable;
88 use Moose::Role;
99
1010 has 'is_paused' => (
1111 is => 'rw',
12 isa => 'Boo',
12 isa => 'Bool',
1313 default => 0,
1414 );
1515
6363 }
6464 }
6565
66 # follow is test
67 do {
66 # This is the actual tests
67 {
6868 my $unreliable = Moose::Meta::Class->create_anon_class(
6969 superclasses => [],
7070 roles => [qw/Restartable::ButUnreliable/],
7474 'load_state' => sub { },
7575 },
7676 )->new_object();
77 ok $unreliable, 'Restartable::ButUnreliable based class';
78 can_ok $unreliable, qw/start stop/, '... can call start and stop';
79 };
77 ok $unreliable, 'made anon class with Restartable::ButUnreliable role';
78 can_ok $unreliable, qw/start stop/;
79 }
8080
81 do {
81 {
8282 my $cnt = 0;
8383 my $broken = Moose::Meta::Class->create_anon_class(
8484 superclasses => [],
8989 'load_state' => sub { },
9090 },
9191 )->new_object();
92 ok $broken, 'Restartable::ButBroken based class';
92 ok $broken, 'made anon class with Restartable::ButBroken role';
9393 $broken->start();
94 is $cnt, 1, '... start is exploded';
94 is $cnt, 1, '... start called explode';
9595 $broken->stop();
96 is $cnt, 2, '... stop is also exploeded';
97 };
96 is $cnt, 2, '... stop also called explode';
97 }
22 use strict;
33 use warnings;
44
5 use Test::More tests => 16;
5 use Test::More tests => 24;
66 use Test::Exception;
77 use Test::Moose;
88
8787 does_ok($bar_attr, 'My::Attribute::Trait');
8888 is($bar_attr->foo, "blah", "attr initialized");
8989
90 ok(!$bar_attr->meta->does_role('Aliased'), "does_role ignores aliases for sanity");
91 ok($bar_attr->does('Aliased'), "attr->does uses aliases");
92 ok(!$bar_attr->meta->does_role('Fictional'), "does_role returns false for nonexistent roles");
93 ok(!$bar_attr->does('Fictional'), "attr->does returns false for nonexistent roles");
94
9095 my $quux = My::Derived::Class->new(bar => 1000);
9196
9297 is($quux->bar, 1000, '... got the right value for bar');
103108
104109 is($derived_bar_attr->the_other_attr, "oink", "attr initialized" );
105110
111 ok(!$derived_bar_attr->meta->does_role('Aliased'), "does_role ignores aliases for sanity");
112 ok($derived_bar_attr->does('Aliased'), "attr->does uses aliases");
113 ok(!$derived_bar_attr->meta->does_role('Fictional'), "does_role returns false for nonexistent roles");
114 ok(!$derived_bar_attr->does('Fictional'), "attr->does returns false for nonexistent roles");
115
106116 can_ok($quux, 'additional_method');
107117 is(eval { $quux->additional_method }, 42, '... got the right value for additional_method');
108118
22 use strict;
33 use warnings;
44
5 use Test::More tests => 35;
5 use Test::More tests => 37;
66 use Test::Exception;
77
88 BEGIN {
4444 ::dies_ok { extends() } '... extends() is not supported';
4545 ::dies_ok { augment() } '... augment() is not supported';
4646 ::dies_ok { inner() } '... inner() is not supported';
47
48 no Moose::Role;
4749 }
4850
4951 my $foo_role = FooRole->meta;
6971 [ sort $foo_role->get_method_list() ],
7072 [ 'boo', 'foo' ],
7173 '... got the right method list');
72
74
75 ok(FooRole->can('foo'), "locally defined methods are still there");
76 ok(!FooRole->can('has'), "sugar was unimported");
77
7378 # attributes ...
7479
7580 is_deeply(
22 use strict;
33 use warnings;
44
5 use Test::More tests => 31;
5 use Test::More tests => 36;
66 use Test::Exception;
77
88 BEGIN {
5959 }
6060
6161 ok(My::OtherRole->meta->has_method($_), "we have a $_ method") for qw(foo baz role_bar);
62 ok(My::OtherRole->meta->requires_method('bar'), '... and the &bar method is required');
62 ok(!My::OtherRole->meta->requires_method('bar'), '... and the &bar method is not required');
6363 ok(!My::OtherRole->meta->requires_method('role_bar'), '... and the &role_bar method is not required');
64
65 {
66 package My::AliasingRole;
67 use Moose::Role;
68
69 ::lives_ok {
70 with 'My::Role' => { alias => { bar => 'role_bar' } };
71 } '... this succeeds';
72 }
73
74 ok(My::AliasingRole->meta->has_method($_), "we have a $_ method") for qw(foo baz role_bar);
75 ok(My::AliasingRole->meta->requires_method('bar'), '... and the &bar method is required');
6476
6577 {
6678 package Foo::Role;