Merge branch 'topic/native-trait-bugfix'
Dave Rolsky [Fri, 19 Nov 2010 15:16:53 +0000 (09:16 -0600)]
Conflicts:
Changes
lib/Moose/Meta/Method/Accessor/Native/Collection.pm

98 files changed:
Changes
lib/Moose/Cookbook/Basics/Recipe8.pod
lib/Moose/Manual/Attributes.pod
lib/Moose/Manual/Contributing.pod
lib/Moose/Manual/Delta.pod
lib/Moose/Manual/Support.pod
lib/Moose/Meta/Attribute.pm
lib/Moose/Meta/Attribute/Native/Trait.pm
lib/Moose/Meta/Attribute/Native/Trait/Array.pm
lib/Moose/Meta/Attribute/Native/Trait/Bool.pm
lib/Moose/Meta/Attribute/Native/Trait/Code.pm
lib/Moose/Meta/Attribute/Native/Trait/Counter.pm
lib/Moose/Meta/Attribute/Native/Trait/Hash.pm
lib/Moose/Meta/Attribute/Native/Trait/Number.pm
lib/Moose/Meta/Attribute/Native/Trait/String.pm
lib/Moose/Meta/Class.pm
lib/Moose/Meta/Method/Accessor.pm
lib/Moose/Meta/Method/Accessor/Native.pm
lib/Moose/Meta/Method/Accessor/Native/Array.pm
lib/Moose/Meta/Method/Accessor/Native/Array/Writer.pm
lib/Moose/Meta/Method/Accessor/Native/Array/accessor.pm
lib/Moose/Meta/Method/Accessor/Native/Array/clear.pm
lib/Moose/Meta/Method/Accessor/Native/Array/count.pm
lib/Moose/Meta/Method/Accessor/Native/Array/delete.pm
lib/Moose/Meta/Method/Accessor/Native/Array/elements.pm
lib/Moose/Meta/Method/Accessor/Native/Array/first.pm
lib/Moose/Meta/Method/Accessor/Native/Array/get.pm
lib/Moose/Meta/Method/Accessor/Native/Array/grep.pm
lib/Moose/Meta/Method/Accessor/Native/Array/insert.pm
lib/Moose/Meta/Method/Accessor/Native/Array/is_empty.pm
lib/Moose/Meta/Method/Accessor/Native/Array/join.pm
lib/Moose/Meta/Method/Accessor/Native/Array/map.pm
lib/Moose/Meta/Method/Accessor/Native/Array/natatime.pm
lib/Moose/Meta/Method/Accessor/Native/Array/pop.pm
lib/Moose/Meta/Method/Accessor/Native/Array/push.pm
lib/Moose/Meta/Method/Accessor/Native/Array/reduce.pm
lib/Moose/Meta/Method/Accessor/Native/Array/set.pm
lib/Moose/Meta/Method/Accessor/Native/Array/shift.pm
lib/Moose/Meta/Method/Accessor/Native/Array/shuffle.pm
lib/Moose/Meta/Method/Accessor/Native/Array/sort.pm
lib/Moose/Meta/Method/Accessor/Native/Array/sort_in_place.pm
lib/Moose/Meta/Method/Accessor/Native/Array/splice.pm
lib/Moose/Meta/Method/Accessor/Native/Array/uniq.pm
lib/Moose/Meta/Method/Accessor/Native/Array/unshift.pm
lib/Moose/Meta/Method/Accessor/Native/Bool/not.pm
lib/Moose/Meta/Method/Accessor/Native/Bool/set.pm
lib/Moose/Meta/Method/Accessor/Native/Bool/toggle.pm
lib/Moose/Meta/Method/Accessor/Native/Bool/unset.pm
lib/Moose/Meta/Method/Accessor/Native/Code/execute.pm
lib/Moose/Meta/Method/Accessor/Native/Code/execute_method.pm
lib/Moose/Meta/Method/Accessor/Native/Collection.pm
lib/Moose/Meta/Method/Accessor/Native/Counter/Writer.pm
lib/Moose/Meta/Method/Accessor/Native/Counter/dec.pm
lib/Moose/Meta/Method/Accessor/Native/Counter/inc.pm
lib/Moose/Meta/Method/Accessor/Native/Counter/reset.pm
lib/Moose/Meta/Method/Accessor/Native/Counter/set.pm
lib/Moose/Meta/Method/Accessor/Native/Hash.pm
lib/Moose/Meta/Method/Accessor/Native/Hash/Writer.pm
lib/Moose/Meta/Method/Accessor/Native/Hash/accessor.pm
lib/Moose/Meta/Method/Accessor/Native/Hash/clear.pm
lib/Moose/Meta/Method/Accessor/Native/Hash/count.pm
lib/Moose/Meta/Method/Accessor/Native/Hash/defined.pm
lib/Moose/Meta/Method/Accessor/Native/Hash/delete.pm
lib/Moose/Meta/Method/Accessor/Native/Hash/elements.pm
lib/Moose/Meta/Method/Accessor/Native/Hash/exists.pm
lib/Moose/Meta/Method/Accessor/Native/Hash/get.pm
lib/Moose/Meta/Method/Accessor/Native/Hash/is_empty.pm
lib/Moose/Meta/Method/Accessor/Native/Hash/keys.pm
lib/Moose/Meta/Method/Accessor/Native/Hash/kv.pm
lib/Moose/Meta/Method/Accessor/Native/Hash/set.pm
lib/Moose/Meta/Method/Accessor/Native/Hash/values.pm
lib/Moose/Meta/Method/Accessor/Native/Number/abs.pm
lib/Moose/Meta/Method/Accessor/Native/Number/add.pm
lib/Moose/Meta/Method/Accessor/Native/Number/div.pm
lib/Moose/Meta/Method/Accessor/Native/Number/mod.pm
lib/Moose/Meta/Method/Accessor/Native/Number/mul.pm
lib/Moose/Meta/Method/Accessor/Native/Number/set.pm
lib/Moose/Meta/Method/Accessor/Native/Number/sub.pm
lib/Moose/Meta/Method/Accessor/Native/Reader.pm
lib/Moose/Meta/Method/Accessor/Native/String/append.pm
lib/Moose/Meta/Method/Accessor/Native/String/chomp.pm
lib/Moose/Meta/Method/Accessor/Native/String/chop.pm
lib/Moose/Meta/Method/Accessor/Native/String/clear.pm
lib/Moose/Meta/Method/Accessor/Native/String/inc.pm
lib/Moose/Meta/Method/Accessor/Native/String/length.pm
lib/Moose/Meta/Method/Accessor/Native/String/match.pm
lib/Moose/Meta/Method/Accessor/Native/String/prepend.pm
lib/Moose/Meta/Method/Accessor/Native/String/replace.pm
lib/Moose/Meta/Method/Accessor/Native/String/substr.pm
lib/Moose/Meta/Method/Accessor/Native/Writer.pm
lib/Moose/Meta/Method/Constructor.pm
lib/Moose/Meta/Method/Destructor.pm
lib/Moose/Meta/Role.pm
lib/Moose/Meta/Role/Application/ToClass.pm
lib/Moose/Util/TypeConstraints.pm
t/010_basics/012_rebless.t
t/030_roles/046_role_attr_application.t [new file with mode: 0644]
t/050_metaclasses/052_metaclass_compat.t

diff --git a/Changes b/Changes
index 4501c9b..a99d871 100644 (file)
--- a/Changes
+++ b/Changes
@@ -3,6 +3,22 @@ for, noteworthy changes.
 
 NEXT
 
+  [API CHANGES]
+
+  * Roles now have their own default attribute metaclass to use during
+    application to a class, rather than just using the class's
+    attribute_metaclass. This is also overridable via ::MetaRole, with the
+    applied_attribute key in the role_metaroles hashref (doy).
+
+  * The internal code used to generate inlined methods (accessor, constructor,
+    etc.) has been massively rewritten. MooseX modules that do inlining will
+    almost certainly need to be updated as well.
+
+  [ENHANCEMENTS]
+
+  * We now load the roles needed for native delegations only as needed. This
+    speeds up the compilation time for Moose itself. (doy)
+
   [BUG FIXES]
 
   * When using native delegations, if an array or hash ref member failed a
index 2d585c7..d748da9 100644 (file)
@@ -100,7 +100,7 @@ do the right thing with the C<predicate> and C<clearer>, making them
 both start with an underscore. The C<builder> method I<always> starts
 with an underscore.
 
-You can read more about C<lazy_build> in L<Moose::Manual::Attributes>
+You can read more about C<lazy_build> in L<Moose::Meta::Attribute>
 
 =head1 CONCLUSION
 
index 94207db..83bfb8a 100644 (file)
@@ -414,7 +414,7 @@ set:
       }
 
       $msg .= " - size is now $size";
-      warn $msg.
+      warn $msg;
   }
 
 The trigger is called I<after> an attribute's value is set. It is
index fae4462..90a00ec 100644 (file)
@@ -62,23 +62,15 @@ L<gitmo@git.moose.perl.org:Moose.git>
 
 =back
 
-=item Core Committers - people reviewing and merging a branch
-
-These people have worked with the Moose codebase for a while.
-
-They've been responsible for large features or branches and can help review
-your changes and apply them to the master branch using the basic
-L</APPROVAL WORKFLOW>.
-
-They are also fairly well versed in Git, in order to merge the branches with
-no mistakes (especially when the merge fails), and to provide advice to
-contributors.
-
 =item Cabal - people who can release moose
 
 These people are the ones who have co-maint on Moose itself and can create a
 release. They're listed under L<Moose/CABAL> in the Moose documentation. They
-merge from Master to Stable.
+are responsible for reviewing branches, and are the only people who are allowed
+to push to stable branches.
+
+Cabal members are listed in L<Moose> and can often be found on irc in the
+L<irc://irc.perl.org/#moose-dev> channel.
 
 =back
 
@@ -89,29 +81,51 @@ everyone involved. The branches below are ordered by level of stability.
 
 =over
 
-=item Stable (refs/heads/stable)
+=item stable/*
+
+The branch from which releases are cut. When making a new major release, the
+release manager makes a new C<stable/$version> branch at the current position
+of C<master>. For minor releases, patches will be committed to C<master>, and
+backported (cherry-picked) to the appropriate stable branch as needed. The
+C<stable> branch is only updated by someone from the Cabal during a release.
 
-The branch from which releases are cut. When making a new release, the
-release manager merges from master to stable. The stable branch is only
-updated by someone from the Cabal during a release.
+=item master
 
-=item Master (refs/heads/master)
+The main development branch. All new code should be written against this
+branch. This branch contains code that has been reviewed, and will be included
+in the next major release. Commits which are judged to not break backwards
+compatibility may be backported into C<stable> to be included in the next minor
+release.
 
-The branch for new development. This branch is merged into and branched from.
+=item rfc/*
 
-=item Branches (refs/heads/*)
+Topic branches that are completed and waiting on review. A Cabal member will
+look over branches in this namespace, and either merge them to C<master> if
+they are acceptable, or move them back to a different namespace otherwise.
 
-Large community branches for big development "projects".
+=item topic/*
 
-=item Topics (refs/heads/topic/*)
+Small personal branches that are still in progress. They can be freely rebased.
+They contain targeted features that may span a handful of commits. Any change
+or bugfix should be created in a topic branch.
 
-Small personal branches that have been published for review, but can get
-freely rebased. Targeted features that may span a handful of commits.
+=item attic/*
 
-Any change or bugfix should be created in a topic branch.
+Branches which have been reviewed, and rejected. They remain in the repository
+in case we later change our mind, or in case parts of them are still useful.
+
+=item abandoned/*
+
+Topic branches which have had no activity for a long period of time will be
+moved here, to keep the main areas clean.
 
 =back
 
+Larger, longer term branches can also be created in the root namespace (i.e.
+at the same level as master and stable). This may be appropriate if multiple
+people are intending to work on the branch. These branches should not be
+rebased without checking with other developers first.
+
 =head1 STANDARD WORKFLOW
 
     # update your copy of master
@@ -119,47 +133,30 @@ Any change or bugfix should be created in a topic branch.
     git pull --rebase
 
     # create a new topic branch
-    git checkout -b topic/my-feature origin/master
+    git checkout -b topic/my-feature
 
     # hack, commit, feel free to break fast forward
-    git commit --amend                       # allowed
-    git rebase --interactive                 # allowed
-    git push --force origin topic/my_feature # allowed
-
-Then ask for a review/approval (see L</APPROVAL WORKFLOW>), and merge
-to master. If it merges cleanly and nobody has any objections, then it
-can be pushed to master.
-
-If it doesn't merge as a fast forward, the author of the branch needs to run
+    git commit --amend        # allowed
+    git rebase --interactive  # allowed
+    git push --force          # allowed
 
+    # keep the branch rebased on top of master, for easy reviewing
     git remote update
-    git rebase origin/master # or merge
+    git rebase origin/master
+    git push --force
 
-and bring the branch up to date, so that it can be merged as a fast forward
-into master.
-
-No actual merging (as in a human resolving conflicts) should be done when
-merging into master, only from master into other branches.
-
-=head2 Preparing a topic branch
-
-Before a merge, a topic branch can be cleaned up by the author.
-
-This can be done using interactive rebase to combine commits, etc, or even
-C<git merge --squash> to make the whole topic into a single commit.
-
-Structuring changes like this makes it easier to apply git revert at a later
-date, and encourages a clean and descriptive history that documents what the
-author was trying to do, without the various hangups that happened while they
-were trying to do it (commits like "oops forgot that file" are not only
-unnecessary noise, they also make running things like git bisect or git revert
-harder).
+    # when finished, move the branch to the rfc/ namespace
+    git branch -m rfc/my-feature
+    git push
+    git push origin :topic/my-feature
 
-However, by far the biggest benefit is that the number of commits that go into
-master is eventually reduced, and they are simple and coherent, making it much
-easier for people maintaining branches to stay up to date.
+When your branch is completed, make sure it has been moved to the C<rfc/>
+namespace and is rebased on top of master, and ask for review/approval (see
+L</APPROVAL WORKFLOW>). If it is approved, the reviewer will merge it into
+C<master>.
 
-All large changes should be documented in L<Moose::Manual::Delta>.
+No actual merging (as in a human resolving conflicts) should be done when
+merging into C<master>, only from C<master> into other branches.
 
 =head1 APPROVAL WORKFLOW
 
@@ -170,8 +167,8 @@ guidelines that ensures all new code is properly vetted before it is merged to
 the master branch.
 
 It should be noted that if you want your specific branch to be approved, it is
-B<your> responsibility to follow this process and advocate for your branch.
-The preferred way is to send a request to the mailing list for review/approval,
+B<your> responsibility to follow this process and advocate for your branch. The
+preferred way is to send a request to the mailing list for review/approval;
 this allows us to better keep track of the branches awaiting approval and those
 which have been approved.
 
@@ -180,7 +177,8 @@ which have been approved.
 =item Small bug fixes, doc patches and additional passing tests.
 
 These items don't really require approval beyond one of the core contributors
-just doing a simple review.
+just doing a simple review. For especially simple patches (doc patches
+especially), committing directly to master is fine.
 
 =item Larger bug fixes, doc additions and TODO or failing tests.
 
@@ -192,7 +190,7 @@ member for accuracy.
 
 TODO tests are basically feature requests, see our L</NEW FEATURES> section
 for more information on that. If your feature needs core support, create a
-topic/ branch using the L</STANDARD WORKFLOW> and start hacking away.
+C<topic/> branch using the L</STANDARD WORKFLOW> and start hacking away.
 
 Failing tests are basically bug reports. You should find a core contributor
 and/or cabal member to see if it is a real bug, then submit the bug and your
@@ -218,8 +216,9 @@ branch's approval.
 
 =item Backwards incompatible changes.
 
-Anything that breaks backwards compatibility must be discussed by the cabal
-and agreed to by a majority of the members.
+Anything that breaks backwards compatibility must be discussed by the
+cabal. Backwards incompatbible changes should not be merged to master if there
+are strong objections for any cabal members.
 
 We have a policy for what we see as sane L</BACKWARDS COMPATIBILITY> for
 Moose. If your changes break back-compat, you must be ready to discuss and
@@ -229,19 +228,27 @@ defend your change.
 
 =head1 RELEASE WORKFLOW
 
+    # major releases (including trial releases)
     git checkout master
+
+    # minor releases
+    git checkout stable
+
     # edit for final version bumping, changelogging, etc
     # prepare release (test suite etc)
     perl-reversion -bump
     make manifest
     git commit
-    git checkout stable
-    git merge master # must be a fast forward
-    git push both
+    git branch stable/2.XXYY # only for non-trial major releases
     shipit # does not ship the tarball, but does everything else
-    cpan-upload ~/shipit-dist/Moose-X.YZ.tar.gz
 
-Development releases are made without merging into the stable branch.
+    # non-trial releases
+    cpan-upload ~/shipit-dist/Moose-2.XXYY.tar.gz
+
+    # trial releases
+    cd ~/shipit-dist
+    mv Moose-2.XXYY.tar.gz Moose-2.XXYY-TRIAL.tar.gz
+    cpan-upload Moose-2.XXYY-TRIAL.tar.gz
 
 =head2 Release How-To
 
@@ -276,21 +283,23 @@ doing the final release steps by hand.
 
 =head1 EMERGENCY BUG WORKFLOW (for immediate release)
 
-Anyone can create the necessary fix by branching off of the stable branch:
+The stable branch exists for easily making bug fix releases.
 
     git remote update
-    git checkout -b topic/my-emergency-fix origin/stable
+    git checkout -b topic/my-emergency-fix origin/master
     # hack
     git commit
 
-Then a cabal member merges into stable:
+Then a cabal member merges into C<master>, and backports the change into
+C<stable>:
 
-    git checkout stable
+    git checkout master
     git merge topic/my-emergency-fix
     git push
+    git checkout stable
+    git cherry-pick -x master
+    git push
     # release
-    git checkout master
-    git merge stable
 
 =head1 PROJECT WORKFLOW
 
@@ -317,44 +326,16 @@ merged into master:
 (unfortunately Git will not allow C<my-project/foo> as a branch name if
 C<my-project> is a valid ref).
 
-=head1 THE "PU" BRANCH
-
-To make things easier for longer lived branches (whether topics or projects),
-the 'pu' branch is basically what happens if you merge all of the branches and
-topics together with master.
-
-We can update this as necessary (e.g. on a weekly basis if there is merit),
-notifying the authors of the respective branches if their branches did not merge
-(and why).
-
-To update 'pu':
-
-    git checkout pu
-    git remote update
-    git reset --hard origin/master
-    git merge @all_the_branches
-
-If the merge is clean, 'pu' is updated with C<push --force>.
-
-If the merge is not clean, the offending branch is removed from
-C<@all_the_branches>, with a small note of the conflict, and we try again.
-
-The authors of the failed branches should be told to try to merge their branch
-into 'pu', to see how their branch interacts with other branches.
-
-'pu' is probably broken most of the time, but lets us know how the different
-branches interact.
-
 =head1 BRANCH ARCHIVAL
 
 Merged branches should be deleted.
 
-Failed branches may be kept, but consider moving to refs/attic/ (e.g.
-http://danns.co.uk/node/295) to keep git branch -l current.
+Failed branches may be kept, but should be moved to C<attic/> to differentiate
+them from in-progress topic branches.
 
 Branches that have not been worked on for a long time will be moved to
-refs/abandoned/ periodically, but feel free to move the branch back to
-refs/topic/ if you want to start working on it again.
+C<abandoned/> periodically, but feel free to move the branch back to C<topic/>
+if you want to start working on it again.
 
 =head1 TESTS, TESTS, TESTS
 
@@ -368,8 +349,19 @@ Moose/Class::MOP and your test exercises this feature in a non-obvious
 way, please add some comments either near the code in question or in
 the test so that others know.
 
-We also greatly appreciate documentation to go with your changes, and
-an entry in the Changes file. Make sure to give yourself credit!
+We also greatly appreciate documentation to go with your changes, and an entry
+in the Changes file. Make sure to give yourself credit! Major changes or new
+user-facing features should also be documented in L<Moose::Manual::Delta>.
+
+=head1 DOCS, DOCS, DOCS
+
+Any user-facing changes must be accompanied by documentation. If you're not
+comfortable writing docs yourself, you might be able to convince another Moose
+dev to help you.
+
+Our goal is to make sure that all features are documented. Undocumented
+features are not considered part of the API when it comes to determining
+whether a change is backwards compatible.
 
 =head1 BACKWARDS COMPATIBILITY
 
@@ -380,16 +372,8 @@ frivolous with our changes, quite the opposite, just that we are not
 afraid of change and will do our best to keep it as painless as
 possible for the end user.
 
-The rule is that if you do something that is not backwards compatible, you
-B<must> do I<at least> one deprecation cycle (more if it is larger change).
-For really larger or radical changes dev releases may be needed as well (the
-Cabal will decide on this on a case-per-case basis).
-
-Our policy with deprecation is that each deprecation should go through several
-stages. First, we simply add a deprecation notice the documentation in
-F<Changes> and L<Moose::Manual::Delta>. In a future release, we then make the
-deprecated feature warn loudly and often so that users will have time to fix
-their usages. Finally, the feature is removed in a later release.
+Our policy for handling backwards compatibility is documented in more detail in
+L<Moose::Manual::Support>.
 
 All backwards incompatible changes B<must> be documented in
 L<Moose::Manual::Delta>. Make sure to document any useful tips or workarounds
@@ -403,6 +387,8 @@ Chris (perigrin) Prather
 
 Yuval (nothingmuch) Kogman
 
+Jesse Luehrs E<lt>doy at tozt dot netE<gt>
+
 =head1 COPYRIGHT AND LICENSE
 
 Copyright 2009 by Infinity Interactive, Inc.
index f4c2b5e..4a147c8 100644 (file)
@@ -16,6 +16,34 @@ feature.  If you encounter a problem and have a solution but don't see
 it documented here, or think we missed an important feature, please
 send us a patch.
 
+=head1 NEXT
+
+=over 4
+
+=item Roles have their own default attribute metaclass
+
+Previously, when a role was applied to a class, it would use the attribute
+metaclass defined in the class when copying over the attributes in the role.
+This was wrong, because for instance, using L<MooseX::FollowPBP> in the class
+would end up renaming all of the accessors generated by the role, some of which
+may be being called in the role, causing it to break. Roles now keep track of
+their own attribute metaclass to use by default when being applied to a class
+(defaulting to Moose::Meta::Attribute). This is modifiable using
+L<Moose::Util::MetaRole> by passing the C<applied_attribute> key to the
+C<role_metaroles> option, as in:
+
+    Moose::Util::MetaRole::apply_metaroles(
+        for => __PACKAGE__,
+        class_metaroles => {
+            attribute => ['My::Meta::Role::Attribute'],
+        },
+        role_metaroles => {
+            applied_attribute => ['My::Meta::Role::Attribute'],
+        },
+    );
+
+=back
+
 =head1 1.16
 
 =over 4
index 2b7b7db..f2234ca 100644 (file)
@@ -5,28 +5,65 @@
 Moose::Manual::Support - Policies regarding support, releases, and
 compatibility.
 
+=head1 SUPPORT POLICY
+
+There are two principles to Moose's policy of supported behavior.
+
+=over 4
+
+=item 1.
+
+Moose favors correctness over everything.
+
+=item 2.
+
+Moose supports documented and tested behavior, not accidental behavior or side
+effects.
+
+=back
+
+If a behavior has never been documented or tested, the behavior is
+I<officially> undefined. Relying upon undocumented and untested behavior is
+done at your own risk.
+
+If a behavior is documented or tested but found to be incorrect later, the
+behavior will go through a deprecation period. During the deprecation period,
+use of that feature will cause a warning. Eventually, the deprecated feature
+will be removed.
+
 =head1 RELEASE SCHEDULE
 
-Moose uses the release early, release often philosophy. Moose is not
-released on a schedule. Releases happen as new features and bug fixes
-are required.
+Moose is on a system of weekly minor releases and quarterly major releases. A
+minor release is defined as one that makes every attempt to preserve backwards
+compatibility. Currently this means that we did not introduce any new
+dependency conflicts, and that we did not make any changes to documented,
+tested behavior. A minor release can include new features and bug fixes.
 
-Moose has historically been released fairly often, and most releases include
-just a few features or bug fixes.
+Major releases may be backwards incompatible. Moose prioritizes
+correctness over backwards compatibility or performance; see the L<Deprecation
+Policy> to understand how backwards incompatible changes are announced.
+
+Before a major release, a series of development releases will be made so that
+users can test the upcoming major release before it is distributed to CPAN. It
+is in the best interests of everyone involved if these releases are tested as
+widely as possible.
 
 =head1 DEPRECATION POLICY
 
 Moose has always prioritized correctness over performance and backwards
 compatibility.
 
-Major deprecations or API changes are first documented in the Changes
-file as well as in L<Moose::Manual::Delta>.
+Major deprecations or API changes are documented in the Changes file as well
+as in L<Moose::Manual::Delta>. The Moose developers will also make an effort
+to warn users of upcoming deprecations and breakage through the Moose blog
+(http://blog.moose.perl.org).
 
-Moose then attempts to warn for deprecated features and API changes for
-a reasonable number of releases before breaking any tested API.
+Deprecated APIs will be preserved for at least one year I<after the major
+release which deprecates that API>. Deprecated APIs will only be removed in a
+major release.
 
-Moose will also warn during installation if the version being installed
-will break a known installed dependency. Unfortunately due to the nature
+Moose will also warn during installation if the version of Moose being
+installed will break an installed dependency. Unfortunately, due to the nature
 of the Perl install process these warnings may be easy to miss.
 
 =head1 BACKWARDS COMPATIBILITY
@@ -41,15 +78,21 @@ C<xt/author/test-my-dependents.t>.
 
 =head1 VERSION NUMBERS
 
-Moose's version numbers are monotonically incrementing two decimal
-values. The version numbers in Moose are I<not> semantic. This means
-that version 1.00 will be the hundredth release, nothing more.
+Moose version numbers consist of three parts, in the form X.YYZZ. The X is the
+"special magic number" that only gets changed for really big changes. Think of
+this as being like the "5" in Perl 5.12.1.
+
+The YY portion is the major version number. Moose uses even numbers for stable
+releases, and odd numbers for trial releases. The ZZ is the minor version, and
+it simply increases monotonically. It starts at "00" each time a new major
+version is released.
+
+Semantically, this means that any two releases which share a major version
+should be API-compatible with each other. In other words, 2.0200, 2.0201, and
+2.0274 are all API-compatible.
 
-Occasionally, we will release a test release with a version like
-0.90_03. These versions may be less stable than non-test releases, and exist
-so that developers can test potentially code-breaking changes. By default, the
-CPAN client will not install a distribution which has an underscore in its
-version.
+Prior to version 2.0, Moose version numbers were monotonically incrementing
+two decimal values (0.01, 0.02, ... 1.11, 1.12, etc.).
 
 Moose was declared production ready at version 0.18 (via L<<
 http://www.perlmonks.org/?node_id=608144 >>).
index 1e8a6a3..f76257a 100644 (file)
@@ -52,6 +52,11 @@ sub throw_error {
     goto $handler;
 }
 
+sub _inline_throw_error {
+    my ( $self, $msg, $args ) = @_;
+    "\$meta->throw_error($msg" . ($args ? ", $args" : "") . ")"; # FIXME makes deparsing *REALLY* hard
+}
+
 sub new {
     my ($class, $name, %options) = @_;
     $class->_process_options($name, \%options) unless $options{__hack_no_process_options}; # used from clone()... YECHKKK FIXME ICKY YUCK GROSS
@@ -509,29 +514,13 @@ sub _call_builder {
 
 ## Slot management
 
-# FIXME:
-# this duplicates too much code from
-# Class::MOP::Attribute, we need to
-# refactor these bits eventually.
-# - SL
-sub _set_initial_slot_value {
-    my ($self, $meta_instance, $instance, $value) = @_;
-
-    my $slot_name = $self->name;
-
-    return $meta_instance->set_slot_value($instance, $slot_name, $value)
-        unless $self->has_initializer;
-
-    my $callback = sub {
-        my $val = $self->_coerce_and_verify( shift, $instance );;
-
-        $meta_instance->set_slot_value($instance, $slot_name, $val);
+sub _make_initializer_writer_callback {
+    my $self = shift;
+    my ($meta_instance, $instance, $slot_name) = @_;
+    my $old_callback = $self->SUPER::_make_initializer_writer_callback(@_);
+    return sub {
+        $old_callback->($self->_coerce_and_verify($_[0], $instance));
     };
-
-    my $initializer = $self->initializer;
-
-    # most things will just want to set a value, so make it first arg
-    $instance->$initializer($value, $callback, $self);
 }
 
 sub set_value {
@@ -562,6 +551,144 @@ sub set_value {
     }
 }
 
+sub _inline_set_value {
+    my $self = shift;
+    my ($instance, $value, $tc, $tc_obj, $for_constructor) = @_;
+
+    my $old   = '@old';
+    my $copy  = '$val';
+    $tc     ||= '$type_constraint';
+    $tc_obj ||= '$type_constraint_obj';
+
+    my @code;
+    if ($self->_writer_value_needs_copy) {
+        push @code, $self->_inline_copy_value($value, $copy);
+        $value = $copy;
+    }
+
+    # constructors already handle required checks
+    push @code, $self->_inline_check_required
+        unless $for_constructor;
+
+    push @code, $self->_inline_tc_code($value, $tc, $tc_obj);
+
+    # constructors do triggers all at once at the end
+    push @code, $self->_inline_get_old_value_for_trigger($instance, $old)
+        unless $for_constructor;
+
+    push @code, (
+        $self->SUPER::_inline_set_value($instance, $value),
+        $self->_inline_weaken_value($instance, $value),
+    );
+
+    # constructors do triggers all at once at the end
+    push @code, $self->_inline_trigger($instance, $value, $old)
+        unless $for_constructor;
+
+    return @code;
+}
+
+sub _writer_value_needs_copy {
+    my $self = shift;
+    return $self->should_coerce;
+}
+
+sub _inline_copy_value {
+    my $self = shift;
+    my ($value, $copy) = @_;
+
+    return 'my ' . $copy . ' = ' . $value . ';'
+}
+
+sub _inline_check_required {
+    my $self = shift;
+
+    return unless $self->is_required;
+
+    my $attr_name = quotemeta($self->name);
+
+    return (
+        'if (@_ < 2) {',
+            $self->_inline_throw_error(
+                '"Attribute (' . $attr_name . ') is required, so cannot '
+              . 'be set to undef"' # defined $_[1] is not good enough
+            ) . ';',
+        '}',
+    );
+}
+
+sub _inline_tc_code {
+    my $self = shift;
+    return (
+        $self->_inline_check_coercion(@_),
+        $self->_inline_check_constraint(@_),
+    );
+}
+
+sub _inline_check_coercion {
+    my $self = shift;
+    my ($value, $tc, $tc_obj) = @_;
+
+    return unless $self->should_coerce && $self->type_constraint->has_coercion;
+
+    return $value . ' = ' . $tc_obj . '->coerce(' . $value . ');';
+}
+
+sub _inline_check_constraint {
+    my $self = shift;
+    my ($value, $tc, $tc_obj) = @_;
+
+    return unless $self->has_type_constraint;
+
+    my $attr_name = quotemeta($self->name);
+
+    return (
+        'if (!' . $tc . '->(' . $value . ')) {',
+            $self->_inline_throw_error(
+                '"Attribute (' . $attr_name . ') does not pass the type '
+              . 'constraint because: " . '
+              . $tc_obj . '->get_message(' . $value . ')',
+                'data => ' . $value
+            ) . ';',
+        '}',
+    );
+}
+
+sub _inline_get_old_value_for_trigger {
+    my $self = shift;
+    my ($instance, $old) = @_;
+
+    return unless $self->has_trigger;
+
+    return (
+        'my ' . $old . ' = ' . $self->_inline_instance_has($instance),
+            '? ' . $self->_inline_instance_get($instance),
+            ': ();',
+    );
+}
+
+sub _inline_weaken_value {
+    my $self = shift;
+    my ($instance, $value) = @_;
+
+    return unless $self->is_weak_ref;
+
+    my $mi = $self->associated_class->get_meta_instance;
+    return (
+        $mi->inline_weaken_slot_value($instance, $self->name, $value),
+            'if ref ' . $value . ';',
+    );
+}
+
+sub _inline_trigger {
+    my $self = shift;
+    my ($instance, $value, $old) = @_;
+
+    return unless $self->has_trigger;
+
+    return '$attr->trigger->(' . $instance . ', ' . $value . ', ' . $old . ');';
+}
+
 sub _weaken_value {
     my ( $self, $instance ) = @_;
 
@@ -614,6 +741,140 @@ sub get_value {
     }
 }
 
+sub _inline_get_value {
+    my $self = shift;
+    my ($instance, $tc, $tc_obj) = @_;
+
+    my $slot_access = $self->_inline_instance_get($instance);
+    $tc           ||= '$type_constraint';
+    $tc_obj       ||= '$type_constraint_obj';
+
+    return (
+        $self->_inline_check_lazy($instance, $tc, $tc_obj),
+        $self->_inline_return_auto_deref($slot_access),
+    );
+}
+
+sub _inline_check_lazy {
+    my $self = shift;
+    my ($instance, $tc, $tc_obj) = @_;
+
+    return unless $self->is_lazy;
+
+    my $slot_exists = $self->_inline_instance_has($instance);
+
+    return (
+        'if (!' . $slot_exists . ') {',
+            $self->_inline_init_from_default($instance, '$default', $tc, $tc_obj, 'lazy'),
+        '}',
+    );
+}
+
+sub _inline_init_from_default {
+    my $self = shift;
+    my ($instance, $default, $tc, $tc_obj, $for_lazy) = @_;
+
+    if (!($self->has_default || $self->has_builder)) {
+        $self->throw_error(
+            'You cannot have a lazy attribute '
+          . '(' . $self->name . ') '
+          . 'without specifying a default value for it',
+            attr => $self,
+        );
+    }
+
+    return (
+        $self->_inline_generate_default($instance, $default),
+        # intentionally not using _inline_tc_code, since that can be overridden
+        # to do things like possibly only do member tc checks, which isn't
+        # appropriate for checking the result of a default
+        $self->has_type_constraint
+            ? ($self->_inline_check_coercion($default, $tc, $tc_obj, $for_lazy),
+               $self->_inline_check_constraint($default, $tc, $tc_obj, $for_lazy))
+            : (),
+        $self->_inline_init_slot($instance, $default),
+    );
+}
+
+sub _inline_generate_default {
+    my $self = shift;
+    my ($instance, $default) = @_;
+
+    if ($self->has_default) {
+        return 'my ' . $default . ' = $attr->default(' . $instance . ');';
+    }
+    elsif ($self->has_builder) {
+        return (
+            'my ' . $default . ';',
+            'if (my $builder = ' . $instance . '->can($attr->builder)) {',
+                $default . ' = ' . $instance . '->$builder;',
+            '}',
+            'else {',
+                'my $class = ref(' . $instance . ') || ' . $instance . ';',
+                'my $builder_name = $attr->builder;',
+                'my $attr_name = $attr->name;',
+                $self->_inline_throw_error(
+                    '"$class does not support builder method '
+                  . '\'$builder_name\' for attribute \'$attr_name\'"'
+                ) . ';',
+            '}',
+        );
+    }
+    else {
+        $self->throw_error(
+            "Can't generate a default for " . $self->name
+          . " since no default or builder was specified"
+        );
+    }
+}
+
+sub _inline_init_slot {
+    my $self = shift;
+    my ($inv, $value) = @_;
+
+    if ($self->has_initializer) {
+        return '$attr->set_initial_value(' . $inv . ', ' . $value . ');';
+    }
+    else {
+        return $self->_inline_instance_set($inv, $value) . ';';
+    }
+}
+
+sub _inline_return_auto_deref {
+    my $self = shift;
+
+    return 'return ' . $self->_auto_deref(@_) . ';';
+}
+
+sub _auto_deref {
+    my $self = shift;
+    my ($ref_value) = @_;
+
+    return $ref_value unless $self->should_auto_deref;
+
+    my $type_constraint = $self->type_constraint;
+
+    my $sigil;
+    if ($type_constraint->is_a_type_of('ArrayRef')) {
+        $sigil = '@';
+    }
+    elsif ($type_constraint->is_a_type_of('HashRef')) {
+        $sigil = '%';
+    }
+    else {
+        $self->throw_error(
+            'Can not auto de-reference the type constraint \''
+          . $type_constraint->name
+          . '\'',
+            type_constraint => $type_constraint,
+        );
+    }
+
+    return 'wantarray '
+             . '? ' . $sigil . '{ (' . $ref_value . ') || return } '
+             . ': (' . $ref_value . ')';
+}
+
 ## installing accessors
 
 sub accessor_metaclass { 'Moose::Meta::Method::Accessor' }
@@ -690,22 +951,6 @@ sub remove_accessors {
     return;
 }
 
-sub inline_set {
-    my $self = shift;
-    my ( $instance, $value ) = @_;
-
-    my $mi = $self->associated_class->get_meta_instance;
-
-    my $code
-        = $mi->inline_set_slot_value( $instance, $self->slots, $value ) . ";";
-    $code
-        .= $mi->inline_weaken_slot_value( $instance, $self->slots, $value )
-        . "    if ref $value;"
-        if $self->is_weak_ref;
-
-    return $code;
-}
-
 sub install_delegation {
     my $self = shift;
 
@@ -1039,6 +1284,29 @@ is equivalent to this:
       predicate => 'has_size',
   );
 
+
+If your attribute name starts with an underscore (C<_>), then the clearer
+and predicate will as well:
+
+  has '_size' => (
+      is         => 'ro',
+      lazy_build => 1,
+  );
+
+becomes:
+
+  has '_size' => (
+      is        => 'ro',
+      lazy      => 1,
+      builder   => '_build__size',
+      clearer   => '_clear_size',
+      predicate => '_has_size',
+  );
+
+Note the doubled underscore in the builder name. Internally, Moose
+simply prepends the attribute name with "_build_" to come up with the
+builder name.
+
 =item * documentation
 
 An arbitrary string that can be retrieved later by calling C<<
index cef68b7..70dda01 100644 (file)
@@ -169,6 +169,7 @@ sub _native_accessor_class_for {
         . $self->_native_type . '::'
         . $suffix;
 
+    Class::MOP::load_class($role);
     return Moose::Meta::Class->create_anon_class(
         superclasses =>
             [ $self->accessor_metaclass, $self->delegation_metaclass ],
index 71b7fdb..5497fc0 100644 (file)
@@ -6,31 +6,6 @@ our $VERSION   = '1.19';
 $VERSION = eval $VERSION;
 our $AUTHORITY = 'cpan:STEVAN';
 
-use Moose::Meta::Method::Accessor::Native::Array::accessor;
-use Moose::Meta::Method::Accessor::Native::Array::clear;
-use Moose::Meta::Method::Accessor::Native::Array::count;
-use Moose::Meta::Method::Accessor::Native::Array::delete;
-use Moose::Meta::Method::Accessor::Native::Array::elements;
-use Moose::Meta::Method::Accessor::Native::Array::first;
-use Moose::Meta::Method::Accessor::Native::Array::get;
-use Moose::Meta::Method::Accessor::Native::Array::grep;
-use Moose::Meta::Method::Accessor::Native::Array::insert;
-use Moose::Meta::Method::Accessor::Native::Array::is_empty;
-use Moose::Meta::Method::Accessor::Native::Array::join;
-use Moose::Meta::Method::Accessor::Native::Array::map;
-use Moose::Meta::Method::Accessor::Native::Array::natatime;
-use Moose::Meta::Method::Accessor::Native::Array::pop;
-use Moose::Meta::Method::Accessor::Native::Array::push;
-use Moose::Meta::Method::Accessor::Native::Array::reduce;
-use Moose::Meta::Method::Accessor::Native::Array::set;
-use Moose::Meta::Method::Accessor::Native::Array::shift;
-use Moose::Meta::Method::Accessor::Native::Array::shuffle;
-use Moose::Meta::Method::Accessor::Native::Array::splice;
-use Moose::Meta::Method::Accessor::Native::Array::sort;
-use Moose::Meta::Method::Accessor::Native::Array::sort_in_place;
-use Moose::Meta::Method::Accessor::Native::Array::uniq;
-use Moose::Meta::Method::Accessor::Native::Array::unshift;
-
 with 'Moose::Meta::Attribute::Native::Trait';
 
 sub _helper_type { 'ArrayRef' }
index 3fdbdba..49ea089 100644 (file)
@@ -5,11 +5,6 @@ our $VERSION = '1.19';
 $VERSION = eval $VERSION;
 our $AUTHORITY = 'cpan:STEVAN';
 
-use Moose::Meta::Method::Accessor::Native::Bool::not;
-use Moose::Meta::Method::Accessor::Native::Bool::set;
-use Moose::Meta::Method::Accessor::Native::Bool::toggle;
-use Moose::Meta::Method::Accessor::Native::Bool::unset;
-
 with 'Moose::Meta::Attribute::Native::Trait';
 
 sub _default_is  { 'rw' }
index c423de5..f8457da 100644 (file)
@@ -5,9 +5,6 @@ our $VERSION   = '1.19';
 $VERSION = eval $VERSION;
 our $AUTHORITY = 'cpan:STEVAN';
 
-use Moose::Meta::Method::Accessor::Native::Code::execute;
-use Moose::Meta::Method::Accessor::Native::Code::execute_method;
-
 with 'Moose::Meta::Attribute::Native::Trait';
 
 sub _helper_type { 'CodeRef' }
index 0cbf53f..ac0c17a 100644 (file)
@@ -6,11 +6,6 @@ our $VERSION   = '1.19';
 $VERSION = eval $VERSION;
 our $AUTHORITY = 'cpan:STEVAN';
 
-use Moose::Meta::Method::Accessor::Native::Counter::dec;
-use Moose::Meta::Method::Accessor::Native::Counter::inc;
-use Moose::Meta::Method::Accessor::Native::Counter::reset;
-use Moose::Meta::Method::Accessor::Native::Counter::set;
-
 with 'Moose::Meta::Attribute::Native::Trait' =>
     { -excludes => ['_root_types'] };
 
index 9b07e2f..775b735 100644 (file)
@@ -6,20 +6,6 @@ our $VERSION   = '1.19';
 $VERSION = eval $VERSION;
 our $AUTHORITY = 'cpan:STEVAN';
 
-use Moose::Meta::Method::Accessor::Native::Hash::accessor;
-use Moose::Meta::Method::Accessor::Native::Hash::clear;
-use Moose::Meta::Method::Accessor::Native::Hash::count;
-use Moose::Meta::Method::Accessor::Native::Hash::defined;
-use Moose::Meta::Method::Accessor::Native::Hash::delete;
-use Moose::Meta::Method::Accessor::Native::Hash::elements;
-use Moose::Meta::Method::Accessor::Native::Hash::exists;
-use Moose::Meta::Method::Accessor::Native::Hash::get;
-use Moose::Meta::Method::Accessor::Native::Hash::is_empty;
-use Moose::Meta::Method::Accessor::Native::Hash::keys;
-use Moose::Meta::Method::Accessor::Native::Hash::kv;
-use Moose::Meta::Method::Accessor::Native::Hash::set;
-use Moose::Meta::Method::Accessor::Native::Hash::values;
-
 with 'Moose::Meta::Attribute::Native::Trait';
 
 sub _helper_type { 'HashRef' }
index b15158e..2b47e0a 100644 (file)
@@ -5,14 +5,6 @@ our $VERSION   = '1.19';
 $VERSION = eval $VERSION;
 our $AUTHORITY = 'cpan:STEVAN';
 
-use Moose::Meta::Method::Accessor::Native::Number::abs;
-use Moose::Meta::Method::Accessor::Native::Number::add;
-use Moose::Meta::Method::Accessor::Native::Number::div;
-use Moose::Meta::Method::Accessor::Native::Number::mod;
-use Moose::Meta::Method::Accessor::Native::Number::mul;
-use Moose::Meta::Method::Accessor::Native::Number::set;
-use Moose::Meta::Method::Accessor::Native::Number::sub;
-
 with 'Moose::Meta::Attribute::Native::Trait';
 
 sub _helper_type { 'Num' }
index 4536dab..50a1091 100644 (file)
@@ -5,17 +5,6 @@ our $VERSION   = '1.19';
 $VERSION = eval $VERSION;
 our $AUTHORITY = 'cpan:STEVAN';
 
-use Moose::Meta::Method::Accessor::Native::String::append;
-use Moose::Meta::Method::Accessor::Native::String::chomp;
-use Moose::Meta::Method::Accessor::Native::String::chop;
-use Moose::Meta::Method::Accessor::Native::String::clear;
-use Moose::Meta::Method::Accessor::Native::String::inc;
-use Moose::Meta::Method::Accessor::Native::String::length;
-use Moose::Meta::Method::Accessor::Native::String::match;
-use Moose::Meta::Method::Accessor::Native::String::prepend;
-use Moose::Meta::Method::Accessor::Native::String::replace;
-use Moose::Meta::Method::Accessor::Native::String::substr;
-
 with 'Moose::Meta::Attribute::Native::Trait';
 
 sub _default_default { q{} }
index 24acd83..67a9972 100644 (file)
@@ -280,6 +280,190 @@ sub new_object {
     return $object;
 }
 
+sub _generate_fallback_constructor {
+    my $self = shift;
+    my ($class) = @_;
+    return $class . '->Moose::Object::new(@_)'
+}
+
+sub _inline_params {
+    my $self = shift;
+    my ($params, $class) = @_;
+    return (
+        'my ' . $params . ' = ',
+        $self->_inline_BUILDARGS($class, '@_'),
+        ';',
+    );
+}
+
+sub _inline_BUILDARGS {
+    my $self = shift;
+    my ($class, $args) = @_;
+
+    my $buildargs = $self->find_method_by_name("BUILDARGS");
+
+    if ($args eq '@_'
+     && (!$buildargs or $buildargs->body == \&Moose::Object::BUILDARGS)) {
+        return (
+            'do {',
+                'my $params;',
+                'if (scalar @_ == 1) {',
+                    'if (!defined($_[0]) || ref($_[0]) ne \'HASH\') {',
+                        $self->_inline_throw_error(
+                            '"Single parameters to new() must be a HASH ref"',
+                            'data => $_[0]',
+                        ) . ';',
+                    '}',
+                    '$params = { %{ $_[0] } };',
+                '}',
+                'elsif (@_ % 2) {',
+                    'Carp::carp(',
+                        '"The new() method for ' . $class . ' expects a '
+                      . 'hash reference or a key/value list. You passed an '
+                      . 'odd number of arguments"',
+                    ');',
+                    '$params = {@_, undef};',
+                '}',
+                'else {',
+                    '$params = {@_};',
+                '}',
+                '$params;',
+            '}',
+        );
+    }
+    else {
+        return $class . '->BUILDARGS(' . $args . ')';
+    }
+}
+
+sub _inline_slot_initializer {
+    my $self  = shift;
+    my ($attr, $idx) = @_;
+
+    return (
+        '## ' . $attr->name,
+        $self->_inline_check_required_attr($attr),
+        $self->SUPER::_inline_slot_initializer(@_),
+    );
+}
+
+sub _inline_check_required_attr {
+    my $self = shift;
+    my ($attr) = @_;
+
+    return unless defined $attr->init_arg;
+    return unless $attr->can('is_required') && $attr->is_required;
+    return if $attr->has_default || $attr->has_builder;
+
+    return (
+        'if (!exists $params->{\'' . $attr->init_arg . '\'}) {',
+            $self->_inline_throw_error(
+                '"Attribute (' . quotemeta($attr->name) . ') is required"'
+            ) . ';',
+        '}',
+    );
+}
+
+# XXX: these two are duplicated from cmop, because we have to pass the tc stuff
+# through to _inline_set_value - this should probably be fixed, but i'm not
+# quite sure how. -doy
+sub _inline_init_attr_from_constructor {
+    my $self = shift;
+    my ($attr, $idx) = @_;
+
+    my @initial_value = $attr->_inline_set_value(
+        '$instance',
+        '$params->{\'' . $attr->init_arg . '\'}',
+        '$type_constraint_bodies[' . $idx . ']',
+        '$type_constraints[' . $idx . ']',
+        'for constructor',
+    );
+
+    push @initial_value, (
+        '$attrs->[' . $idx . ']->set_initial_value(',
+            '$instance,',
+            $attr->_inline_instance_get('$instance'),
+        ');',
+    ) if $attr->has_initializer;
+
+    return @initial_value;
+}
+
+sub _inline_init_attr_from_default {
+    my $self = shift;
+    my ($attr, $idx) = @_;
+
+    my $default = $self->_inline_default_value($attr, $idx);
+    return unless $default;
+
+    my @initial_value = (
+        'my $default = ' . $default . ';',
+        $attr->_inline_set_value(
+            '$instance',
+            '$default',
+            '$type_constraint_bodies[' . $idx . ']',
+            '$type_constraints[' . $idx . ']',
+            'for constructor',
+        ),
+    );
+
+    push @initial_value, (
+        '$attrs->[' . $idx . ']->set_initial_value(',
+            '$instance,',
+            $attr->_inline_instance_get('$instance'),
+        ');',
+    ) if $attr->has_initializer;
+
+    return @initial_value;
+}
+
+sub _inline_extra_init {
+    my $self = shift;
+    return (
+        $self->_inline_triggers,
+        $self->_inline_BUILDALL,
+    );
+}
+
+sub _inline_triggers {
+    my $self = shift;
+    my @trigger_calls;
+
+    my @attrs = sort { $a->name cmp $b->name } $self->get_all_attributes;
+    for my $i (0 .. $#attrs) {
+        my $attr = $attrs[$i];
+
+        next unless $attr->can('has_trigger') && $attr->has_trigger;
+
+        my $init_arg = $attr->init_arg;
+        next unless defined $init_arg;
+
+        push @trigger_calls,
+            'if (exists $params->{\'' . $init_arg . '\'}) {',
+                '$attrs->[' . $i . ']->trigger->(',
+                    '$instance,',
+                    $attr->_inline_instance_get('$instance') . ',',
+                ');',
+            '}';
+    }
+
+    return @trigger_calls;
+}
+
+sub _inline_BUILDALL {
+    my $self = shift;
+
+    my @methods = reverse $self->find_all_methods_by_name('BUILD');
+    my @BUILD_calls;
+
+    foreach my $method (@methods) {
+        push @BUILD_calls,
+            '$instance->' . $method->{class} . '::BUILD($params);';
+    }
+
+    return @BUILD_calls;
+}
+
 sub superclasses {
     my $self = shift;
     my $supers = Data::OptList::mkopt(\@_);
@@ -478,6 +662,11 @@ sub throw_error {
     $self->raise_error($self->create_error(@args));
 }
 
+sub _inline_throw_error {
+    my ( $self, $msg, $args ) = @_;
+    "\$meta->throw_error($msg" . ($args ? ", $args" : "") . ")"; # FIXME makes deparsing *REALLY* hard
+}
+
 sub raise_error {
     my ( $self, @args ) = @_;
     die @args;
index a293f8e..b3f4b72 100644 (file)
@@ -4,6 +4,8 @@ package Moose::Meta::Method::Accessor;
 use strict;
 use warnings;
 
+use Try::Tiny;
+
 our $VERSION   = '1.19';
 $VERSION = eval $VERSION;
 our $AUTHORITY = 'cpan:STEVAN';
@@ -13,22 +15,25 @@ use base 'Moose::Meta::Method',
 
 sub _error_thrower {
     my $self = shift;
-    ( ref $self && $self->associated_attribute ) || $self->SUPER::_error_thrower();
+    return $self->associated_attribute
+        if ref($self) && defined($self->associated_attribute);
+    return $self->SUPER::_error_thrower;
 }
 
-sub _eval_code {
-    my ( $self, $source ) = @_;
-
-    my $environment = $self->_eval_environment;
-
-    my ( $code, $e ) = $self->_compile_code( environment => $environment, code => $source );
-
-    $self->throw_error(
-        "Could not create writer for '${\$self->associated_attribute->name}' because $e \n code: $source",
-        error => $e, data => $source )
-        if $e;
-
-    return $code;
+sub _compile_code {
+    my $self = shift;
+    my @args = @_;
+    try {
+        $self->SUPER::_compile_code(@args);
+    }
+    catch {
+        $self->throw_error(
+            'Could not create writer for '
+          . "'" . $self->associated_attribute->name . "' "
+          . 'because ' . $_,
+            error => $_,
+        );
+    };
 }
 
 sub _eval_environment {
@@ -43,76 +48,12 @@ sub _eval_environment {
         '$type_constraint_obj' => \$type_constraint_obj,
         '$type_constraint'     => \(
               $type_constraint_obj
-            ? $type_constraint_obj->_compiled_type_constraint
-            : undef
+                  ? $type_constraint_obj->_compiled_type_constraint
+                  : undef
         ),
     };
 }
 
-sub _generate_accessor_method_inline {
-    my $self        = $_[0];
-    my $inv         = '$_[0]';
-    my $value_name  = $self->_value_needs_copy ? '$val' : '$_[1]';
-
-    $self->_eval_code('sub { ' . "\n"
-    . $self->_inline_pre_body(@_) . "\n"
-    . 'if (scalar(@_) >= 2) {' . "\n"
-        . $self->_inline_copy_value . "\n"
-        . $self->_inline_check_required . "\n"
-        . $self->_inline_check_coercion($value_name) . "\n"
-        . $self->_inline_check_constraint($value_name) . "\n"
-        . $self->_inline_get_old_value_for_trigger($inv, $value_name) . "\n"
-        . $self->_inline_store($inv, $value_name) . "\n"
-        . $self->_inline_trigger($inv, $value_name, '@old') . "\n"
-    . ' }' . "\n"
-    . $self->_inline_check_lazy($inv) . "\n"
-    . $self->_inline_post_body(@_) . "\n"
-    . 'return ' . $self->_inline_auto_deref($self->_inline_get($inv)) . "\n"
-    . ' }');
-}
-
-sub _generate_writer_method_inline {
-    my $self        = $_[0];
-    my $inv         = '$_[0]';
-    my $value_name  = $self->_value_needs_copy ? '$val' : '$_[1]';
-
-    $self->_eval_code('sub { '
-    . $self->_inline_pre_body(@_)
-    . $self->_inline_copy_value
-    . $self->_inline_check_required
-    . $self->_inline_check_coercion($value_name)
-    . $self->_inline_check_constraint($value_name)
-    . $self->_inline_get_old_value_for_trigger($inv, $value_name) . "\n"
-    . $self->_inline_store($inv, $value_name)
-    . $self->_inline_post_body(@_)
-    . $self->_inline_trigger($inv, $value_name, '@old')
-    . ' }');
-}
-
-sub _generate_reader_method_inline {
-    my $self        = $_[0];
-    my $inv         = '$_[0]';
-    my $slot_access = $self->_inline_get($inv);
-
-    $self->_eval_code('sub {'
-    . $self->_inline_pre_body(@_)
-    . $self->_inline_throw_error('"Cannot assign a value to a read-only accessor"', 'data => \@_') . ' if @_ > 1;'
-    . $self->_inline_check_lazy($inv)
-    . $self->_inline_post_body(@_)
-    . 'return ' . $self->_inline_auto_deref( $slot_access ) . ';'
-    . '}');
-}
-
-sub _inline_copy_value {
-    return '' unless shift->_value_needs_copy;
-    return 'my $val = $_[1];'
-}
-
-sub _value_needs_copy {
-    my $attr = (shift)->associated_attribute;
-    return $attr->should_coerce;
-}
-
 sub _instance_is_inlinable {
     my $self = shift;
     return $self->associated_attribute->associated_class->instance_metaclass->is_inlinable;
@@ -148,159 +89,40 @@ sub _generate_clearer_method {
                                   : $self->SUPER::_generate_clearer_method(@_);
 }
 
-sub _inline_pre_body  { '' }
-sub _inline_post_body { '' }
-
-sub _inline_check_constraint {
-    my ($self, $value) = @_;
-
-    my $attr = $self->associated_attribute;
-
-    return '' unless $attr->has_type_constraint;
-
-    my $attr_name = quotemeta( $attr->name );
-
-    qq{\$type_constraint->($value) || } . $self->_inline_throw_error(qq{"Attribute ($attr_name) does not pass the type constraint because: " . \$type_constraint_obj->get_message($value)}, "data => $value") . ";";
+sub _writer_value_needs_copy {
+    shift->associated_attribute->_writer_value_needs_copy(@_);
 }
 
-sub _inline_check_coercion {
-    my ($self, $value) = @_;
-
-    my $attr = $self->associated_attribute;
-
-    return '' unless $attr->should_coerce && $attr->type_constraint->has_coercion;
-    return "$value = \$attr->type_constraint->coerce($value);";
+sub _inline_tc_code {
+    shift->associated_attribute->_inline_tc_code(@_);
 }
 
-sub _inline_check_required {
-    my $self = shift;
-    my $attr = $self->associated_attribute;
-
-    return '' unless $attr->is_required;
-
-    my $attr_name = quotemeta( $attr->name );
-
-    return qq{(\@_ >= 2) || } . $self->_inline_throw_error(qq{"Attribute ($attr_name) is required, so cannot be set to undef"}) . ';' # defined $_[1] is not good enough
+sub _inline_check_constraint {
+    shift->associated_attribute->_inline_check_constraint(@_);
 }
 
 sub _inline_check_lazy {
-    my ($self, $instance) = @_;
-
-    my $attr = $self->associated_attribute;
-
-    return '' unless $attr->is_lazy;
-
-    my $slot_exists = $self->_inline_has($instance);
-
-    my $code = 'unless (' . $slot_exists . ') {' . "\n";
-    if ($attr->has_type_constraint) {
-        if ($attr->has_default || $attr->has_builder) {
-            if ($attr->has_default) {
-                $code .= '    my $default = $attr->default(' . $instance . ');'."\n";
-            }
-            elsif ($attr->has_builder) {
-                $code .= '    my $default;'."\n".
-                         '    if(my $builder = '.$instance.'->can($attr->builder)){ '."\n".
-                         '        $default = '.$instance.'->$builder; '. "\n    } else {\n" .
-                         '        ' . $self->_inline_throw_error(q{sprintf "%s does not support builder method '%s' for attribute '%s'", ref(} . $instance . ') || '.$instance.', $attr->builder, $attr->name') .
-                         ';'. "\n    }";
-            }
-            $code .= $self->_inline_check_coercion('$default') . "\n";
-            $code .= $self->_inline_check_constraint('$default', 'lazy') . "\n";
-            $code .= '    ' . $self->_inline_init_slot($attr, $instance, '$default') . "\n";
-        }
-        else {
-            $code .= '    ' . $self->_inline_init_slot($attr, $instance, 'undef') . "\n";
-        }
-
-    } else {
-        if ($attr->has_default) {
-            $code .= '    ' . $self->_inline_init_slot($attr, $instance, ('$attr->default(' . $instance . ')')) . "\n";
-        }
-        elsif ($attr->has_builder) {
-            $code .= '    if (my $builder = '.$instance.'->can($attr->builder)) { ' . "\n"
-                  .  '       ' . $self->_inline_init_slot($attr, $instance, ($instance . '->$builder'))
-                  .  "\n    } else {\n"
-                  .  '        ' . $self->_inline_throw_error(q{sprintf "%s does not support builder method '%s' for attribute '%s'", ref(} . $instance . ') || '.$instance.', $attr->builder, $attr->name')
-                  .  ';'. "\n    }";
-        }
-        else {
-            $code .= '    ' . $self->_inline_init_slot($attr, $instance, 'undef') . "\n";
-        }
-    }
-    $code .= "}\n";
-    return $code;
+    shift->associated_attribute->_inline_check_lazy(@_);
 }
 
-sub _inline_init_slot {
-    my ($self, $attr, $inv, $value) = @_;
-    if ($attr->has_initializer) {
-        return ('$attr->set_initial_value(' . $inv . ', ' . $value . ');');
-    }
-    else {
-        return $self->_inline_store($inv, $value);
-    }
-}
-
-sub _inline_store {
-    my ( $self, $instance, $value ) = @_;
-
-    return $self->associated_attribute->inline_set( $instance, $value );
+sub _inline_store_value {
+    shift->associated_attribute->_inline_instance_set(@_) . ';';
 }
 
 sub _inline_get_old_value_for_trigger {
-    my ( $self, $instance ) = @_;
-
-    my $attr = $self->associated_attribute;
-    return '' unless $attr->has_trigger;
-
-    return
-          'my @old = '
-        . $self->_inline_has($instance) . q{ ? }
-        . $self->_inline_get($instance) . q{ : ()} . ";\n";
+    shift->associated_attribute->_inline_get_old_value_for_trigger(@_);
 }
 
 sub _inline_trigger {
-    my ($self, $instance, $value, $old_value) = @_;
-    my $attr = $self->associated_attribute;
-    return '' unless $attr->has_trigger;
-    return sprintf('$attr->trigger->(%s, %s, %s);', $instance, $value, $old_value);
-}
-
-sub _inline_get {
-    my ($self, $instance) = @_;
-
-    return $self->associated_attribute->inline_get($instance);
+    shift->associated_attribute->_inline_trigger(@_);
 }
 
-sub _inline_has {
-    my ($self, $instance) = @_;
-
-    return $self->associated_attribute->inline_has($instance);
+sub _get_value {
+    shift->associated_attribute->_inline_instance_get(@_);
 }
 
-sub _inline_auto_deref {
-    my ( $self, $ref_value ) = @_;
-        my $attr = $self->associated_attribute;
-
-    return $ref_value unless $attr->should_auto_deref;
-
-    my $type_constraint = $attr->type_constraint;
-
-    my $sigil;
-    if ($type_constraint->is_a_type_of('ArrayRef')) {
-        $sigil = '@';
-    }
-    elsif ($type_constraint->is_a_type_of('HashRef')) {
-        $sigil = '%';
-    }
-    else {
-        $self->throw_error( "Can not auto de-reference the type constraint '"
-                . quotemeta( $type_constraint->name )
-                . "'", type_constraint => $type_constraint );
-    }
-
-    "(wantarray() ? $sigil\{ ( $ref_value ) || return } : ( $ref_value ) )";
+sub _has_value {
+    shift->associated_attribute->_inline_instance_has(@_);
 }
 
 1;
index dd26002..316d5c9 100644 (file)
@@ -17,13 +17,12 @@ around new => sub {
     my $class   = shift;
     my %options = @_;
 
-    exists $options{curried_arguments}
-        || ( $options{curried_arguments} = [] );
+    $options{curried_arguments} = []
+        unless exists $options{curried_arguments};
 
-    ( $options{curried_arguments}
-            && ( 'ARRAY' eq ref $options{curried_arguments} ) )
-        || confess
-        'You must supply a curried_arguments which is an ARRAY reference';
+    confess 'You must supply a curried_arguments which is an ARRAY reference'
+        unless $options{curried_arguments}
+            && ref($options{curried_arguments}) eq 'ARRAY';
 
     $options{definition_context} = $options{attribute}->definition_context;
 
@@ -32,20 +31,19 @@ around new => sub {
     return $class->$orig(%options);
 };
 
-around _new => sub {
-    shift;
+sub _new {
     my $class = shift;
     my $options = @_ == 1 ? $_[0] : {@_};
 
     return bless $options, $class;
-};
+}
 
 sub root_types { (shift)->{'root_types'} }
 
 sub _initialize_body {
     my $self = shift;
 
-    $self->{'body'} = $self->_eval_code( $self->_generate_method );
+    $self->{'body'} = $self->_compile_code( [$self->_generate_method] );
 
     return;
 }
@@ -53,64 +51,75 @@ sub _initialize_body {
 sub _inline_curried_arguments {
     my $self = shift;
 
-    return q{} unless @{ $self->curried_arguments };
+    return unless @{ $self->curried_arguments };
 
-    return 'unshift @_, @curried;'
+    return 'unshift @_, @curried;';
 }
 
 sub _inline_check_argument_count {
     my $self = shift;
 
-    my $code = q{};
-
-    if ( my $min = $self->_minimum_arguments ) {
-        my $err_msg = sprintf(
-            q{"Cannot call %s without at least %s argument%s"},
-            $self->delegate_to_method,
-            $min,
-            ( $min == 1 ? q{} : 's' )
+    my @code;
+
+    if (my $min = $self->_minimum_arguments) {
+        push @code, (
+            'if (@_ < ' . $min . ') {',
+                $self->_inline_throw_error(
+                    sprintf(
+                        '"Cannot call %s without at least %s argument%s"',
+                        $self->delegate_to_method,
+                        $min,
+                        ($min == 1 ? '' : 's'),
+                    )
+                ) . ';',
+            '}',
         );
-
-        $code
-            .= "\n"
-            . $self->_inline_throw_error($err_msg)
-            . " unless \@_ >= $min;";
     }
 
-    if ( defined( my $max = $self->_maximum_arguments ) ) {
-        my $err_msg = sprintf(
-            q{"Cannot call %s with %s argument%s"},
-            $self->delegate_to_method,
-            ( $max ? "more than $max" : 'any' ),
-            ( $max == 1 ? q{} : 's' )
+    if (defined(my $max = $self->_maximum_arguments)) {
+        push @code, (
+            'if (@_ > ' . $max . ') {',
+                $self->_inline_throw_error(
+                    sprintf(
+                        '"Cannot call %s with %s argument%s"',
+                        $self->delegate_to_method,
+                        $max ? "more than $max" : 'any',
+                        ($max == 1 ? '' : 's'),
+                    )
+                ) . ';',
+            '}',
         );
-
-        $code
-            .= "\n"
-            . $self->_inline_throw_error($err_msg)
-            . " if \@_ > $max;";
     }
 
-    return $code;
+    return @code;
+}
+
+sub _inline_return_value {
+    my $self = shift;
+    my ($slot_access, $for_writer) = @_;
+
+    return 'return ' . $self->_return_value($slot_access, $for_writer) . ';';
 }
 
 sub _minimum_arguments { 0 }
 sub _maximum_arguments { undef }
 
-override _inline_get => sub {
-    my ( $self, $instance ) = @_;
+override _get_value => sub {
+    my $self = shift;
+    my ($instance) = @_;
 
     return $self->_slot_access_can_be_inlined
         ? super()
-        : "${instance}->\$reader";
+        : $instance . '->$reader';
 };
 
-override _inline_store => sub {
-    my ( $self, $instance, $value ) = @_;
+override _inline_store_value => sub {
+    my $self = shift;
+    my ($instance, $value) = @_;
 
     return $self->_slot_access_can_be_inlined
         ? super()
-        : "${instance}->\$writer($value)";
+        : $instance . '->$writer(' . $value . ');';
 };
 
 override _eval_environment => sub {
index 224e907..8940384 100644 (file)
@@ -12,12 +12,17 @@ $VERSION = eval $VERSION;
 our $AUTHORITY = 'cpan:STEVAN';
 
 sub _inline_check_var_is_valid_index {
-    my ( $self, $var ) = @_;
-
-    return $self->_inline_throw_error( q{'The index passed to }
-            . $self->delegate_to_method
-            . q{ must be an integer'} )
-        . qq{ unless defined $var && $var =~ /^-?\\d+\$/;};
+    my $self = shift;
+    my ($var) = @_;
+
+    return (
+        'if (!defined(' . $var . ') || ' . $var . ' !~ /^-?\d+$/) {',
+            $self->_inline_throw_error(
+                '"The index passed to ' . $self->delegate_to_method
+              . ' must be an integer"',
+            ) . ';',
+        '}',
+    );
 }
 
 no Moose::Role;
index bf86f5a..2247833 100644 (file)
@@ -9,14 +9,17 @@ our $AUTHORITY = 'cpan:STEVAN';
 
 use Moose::Role;
 
-with 'Moose::Meta::Method::Accessor::Native::Writer',
+with 'Moose::Meta::Method::Accessor::Native::Writer' => {
+        -excludes => ['_inline_coerce_new_values'],
+    },
     'Moose::Meta::Method::Accessor::Native::Array',
     'Moose::Meta::Method::Accessor::Native::Collection';
 
-sub _new_members {'@_'}
+sub _new_members { '@_' }
 
-sub _inline_copy_old_value {
-    my ( $self, $slot_access ) = @_;
+sub _copy_old_value {
+    my $self = shift;
+    my ($slot_access) = @_;
 
     return '[ @{(' . $slot_access . ')} ]';
 }
index ee08424..5fe6fe4 100644 (file)
@@ -32,47 +32,29 @@ with 'Moose::Meta::Method::Accessor::Native::Array::set' => {
 sub _generate_method {
     my $self = shift;
 
-    my $inv = '$self';
-
-    my $code = 'sub {';
-    $code .= "\n" . $self->_inline_pre_body(@_);
-
-    $code .= "\n" . 'my $self = shift;';
-
-    $code .= "\n" . $self->_inline_curried_arguments;
-
-    $code .= "\n" . $self->_inline_check_lazy($inv);
-
-    my $slot_access = $self->_inline_get($inv);
-
-    # get
-    $code .= "\n" . 'if ( @_ == 1 ) {';
-
-    $code .= "\n" . $self->_inline_check_var_is_valid_index('$_[0]');
-
-    $code
-        .= "\n"
-        . 'return '
-        . $self
-        ->Moose::Meta::Method::Accessor::Native::Array::get::_return_value(
-        $slot_access)
-        . ';';
-
-    # set
-    $code .= "\n" . '} else {';
-
-    $code .= "\n" . $self->_writer_core( $inv, $slot_access );
-
-    $code .= "\n" . $self->_inline_post_body(@_);
-
-    $code .= "\n}";
-    $code .= "\n}";
-
-    return $code;
+    my $inv         = '$self';
+    my $slot_access = $self->_get_value($inv);
+
+    return (
+        'sub {',
+            'my ' . $inv . ' = shift;',
+            $self->_inline_curried_arguments,
+            $self->_inline_check_lazy($inv, '$type_constraint', '$type_constraint_obj'),
+            # get
+            'if (@_ == 1) {',
+                $self->_inline_check_var_is_valid_index('$_[0]'),
+                $self->Moose::Meta::Method::Accessor::Native::Array::get::_inline_return_value($slot_access),
+            '}',
+            # set
+            'else {',
+                $self->_inline_writer_core($inv, $slot_access),
+            '}',
+        '}',
+    );
 }
 
-sub _minimum_arguments {1}
-sub _maximum_arguments {2}
+sub _minimum_arguments { 1 }
+sub _maximum_arguments { 2 }
 
 no Moose::Role;
 
index 27d60cd..b4c2ef4 100644 (file)
@@ -23,15 +23,16 @@ sub _maximum_arguments { 0 }
 
 sub _adds_members { 0 }
 
-sub _potential_value { return '[]' }
+sub _potential_value { '[]' }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "$slot_access = []";
+    return $slot_access . ' = [];';
 }
 
-sub _return_value { return q{} }
+sub _return_value { '' }
 
 no Moose::Role;
 
index 945a22b..8b4de0f 100644 (file)
@@ -15,9 +15,10 @@ with 'Moose::Meta::Method::Accessor::Native::Reader' =>
 sub _maximum_arguments { 0 }
 
 sub _return_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "scalar \@{ ($slot_access) }";
+    return 'scalar @{ (' . $slot_access . ') }';
 }
 
 no Moose::Role;
index 06baa74..fc18adf 100644 (file)
@@ -34,22 +34,28 @@ sub _inline_check_arguments {
 sub _adds_members { 0 }
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return
-        "( do { my \@potential = \@{ ($slot_access) }; \@return = splice \@potential, \$_[0], 1; \\\@potential } )";
+    return '(do { '
+             . 'my @potential = @{ (' . $slot_access . ') }; '
+             . '@return = splice @potential, $_[0], 1; '
+             . '\@potential; '
+         . '})';
 }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "\@return = splice \@{ ($slot_access) }, \$_[0], 1";
+    return '@return = splice @{ (' . $slot_access . ') }, $_[0], 1;';
 }
 
 sub _return_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return 'return $return[0];';
+    return '$return[0]';
 }
 
 no Moose::Role;
index 512e444..556655b 100644 (file)
@@ -15,10 +15,10 @@ with 'Moose::Meta::Method::Accessor::Native::Reader' =>
 sub _maximum_arguments { 0 }
 
 sub _return_value {
-    my $self        = shift;
-    my $slot_access = shift;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "\@{ ($slot_access) }";
+    return '@{ (' . $slot_access . ') }';
 }
 
 no Moose::Role;
index fc35c9e..5d4482b 100644 (file)
@@ -29,16 +29,20 @@ sub _maximum_arguments { 1 }
 sub _inline_check_arguments {
     my $self = shift;
 
-    return $self->_inline_throw_error(
-        q{'The argument passed to first must be a code reference'})
-        . q{ unless Params::Util::_CODELIKE( $_[0] );};
+    return (
+        'if (!Params::Util::_CODELIKE($_[0])) {',
+            $self->_inline_throw_error(
+                '"The argument passed to first must be a code reference"',
+            ) . ';',
+        '}',
+    );
 }
 
 sub _return_value {
-    my $self        = shift;
-    my $slot_access = shift;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "&List::Util::first( \$_[0], \@{ ($slot_access) } )";
+    return '&List::Util::first($_[0], @{ (' . $slot_access . ') })';
 }
 
 no Moose::Role;
index b2a79f5..c440270 100644 (file)
@@ -33,10 +33,10 @@ sub _inline_check_arguments {
 }
 
 sub _return_value {
-    my $self        = shift;
-    my $slot_access = shift;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "${slot_access}->[ \$_[0] ]";
+    return $slot_access . '->[ $_[0] ]';
 }
 
 1;
index 2c82f69..389dc65 100644 (file)
@@ -28,16 +28,20 @@ sub _maximum_arguments { 1 }
 sub _inline_check_arguments {
     my $self = shift;
 
-    return $self->_inline_throw_error(
-        q{'The argument passed to grep must be a code reference'})
-        . q{ unless Params::Util::_CODELIKE( $_[0] );};
+    return (
+        'if (!Params::Util::_CODELIKE($_[0])) {',
+            $self->_inline_throw_error(
+                '"The argument passed to grep must be a code reference"',
+            ) . ';',
+        '}',
+    );
 }
 
 sub _return_value {
-    my $self        = shift;
-    my $slot_access = shift;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "grep { \$_[0]->() } \@{ ($slot_access) }";
+    return 'grep { $_[0]->() } @{ (' . $slot_access . ') }';
 }
 
 no Moose::Role;
index ff12580..1c592bf 100644 (file)
@@ -14,6 +14,7 @@ with 'Moose::Meta::Method::Accessor::Native::Array::Writer' => {
         qw(
             _minimum_arguments
             _maximum_arguments
+            _inline_coerce_new_values
             _new_members
             _inline_optimized_set_new_value
             _return_value
@@ -28,37 +29,42 @@ sub _maximum_arguments { 2 }
 sub _adds_members { 1 }
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return
-        "( do { my \@potential = \@{ ($slot_access) }; splice \@potential, \$_[0], 0, \$_[1]; \\\@potential } )";
+    return '(do { '
+             . 'my @potential = @{ (' . $slot_access . ') }; '
+             . 'splice @potential, $_[0], 0, $_[1]; '
+             . '\@potential; '
+         . '})';
 }
 
 # We need to override this because while @_ can be written to, we cannot write
 # directly to $_[1].
-around _inline_coerce_new_values => sub {
-    shift;
+sub _inline_coerce_new_values {
     my $self = shift;
 
-    return q{} unless $self->associated_attribute->should_coerce;
+    return unless $self->associated_attribute->should_coerce;
 
-    return q{} unless $self->_tc_member_type_can_coerce;
+    return unless $self->_tc_member_type_can_coerce;
 
-    return '@_ = ( $_[0], $member_tc_obj->coerce( $_[1] ) );';
+    return '@_ = ($_[0], $member_tc_obj->coerce($_[1]));';
 };
 
 sub _new_members { '$_[1]' }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "splice \@{ ($slot_access) }, \$_[0], 0, \$_[1];";
+    return 'splice @{ (' . $slot_access . ') }, $_[0], 0, $_[1];';
 }
 
 sub _return_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "return ${slot_access}->[ \$_[0] ];";
+    return $slot_access . '->[ $_[0] ]';
 }
 
 no Moose::Role;
index ebcc150..c64c0a3 100644 (file)
@@ -15,10 +15,10 @@ with 'Moose::Meta::Method::Accessor::Native::Reader' =>
 sub _maximum_arguments { 0 }
 
 sub _return_value {
-    my $self        = shift;
-    my $slot_access = shift;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "\@{ ($slot_access) } ? 0 : 1";
+    return '@{ (' . $slot_access . ') } ? 0 : 1';
 }
 
 no Moose::Role;
index 6215e07..40f488e 100644 (file)
@@ -28,16 +28,20 @@ sub _maximum_arguments { 1 }
 sub _inline_check_arguments {
     my $self = shift;
 
-    return $self->_inline_throw_error(
-        q{'The argument passed to join must be a string'})
-        . ' unless Moose::Util::_STRINGLIKE0( $_[0] );';
+    return (
+        'if (!Moose::Util::_STRINGLIKE0($_[0])) {',
+            $self->_inline_throw_error(
+                '"The argument passed to join must be a string"',
+            ) . ';',
+        '}',
+    );
 }
 
 sub _return_value {
-    my $self        = shift;
-    my $slot_access = shift;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "join \$_[0], \@{ ($slot_access) }";
+    return 'join $_[0], @{ (' . $slot_access . ') }';
 }
 
 no Moose::Role;
index f6837b0..07c65f3 100644 (file)
@@ -28,16 +28,20 @@ sub _maximum_arguments { 1 }
 sub _inline_check_arguments {
     my $self = shift;
 
-    return $self->_inline_throw_error(
-        q{'The argument passed to map must be a code reference'})
-        . q{ unless Params::Util::_CODELIKE( $_[0] );};
+    return (
+        'if (!Params::Util::_CODELIKE($_[0])) {',
+            $self->_inline_throw_error(
+                '"The argument passed to map must be a code reference"',
+            ) . ';',
+        '}',
+    );
 }
 
 sub _return_value {
-    my $self        = shift;
-    my $slot_access = shift;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "map { \$_[0]->() } \@{ ($slot_access) }";
+    return 'map { $_[0]->() } @{ (' . $slot_access . ') }';
 }
 
 no Moose::Role;
index 971f3ef..b2ced02 100644 (file)
@@ -23,32 +23,43 @@ with 'Moose::Meta::Method::Accessor::Native::Reader' => {
     ]
 };
 
-sub _minimum_arguments {1}
+sub _minimum_arguments { 1 }
 
-sub _maximum_arguments {2}
+sub _maximum_arguments { 2 }
 
 sub _inline_check_arguments {
     my $self = shift;
 
-    return $self->_inline_throw_error(
-        q{'The n value passed to natatime must be an integer'})
-        . ' unless defined $_[0] && $_[0] =~ /^\\d+$/;' . "\n"
-        . $self->_inline_throw_error(
-        q{'The second argument passed to natatime must be a code reference'})
-        . q{ if @_ == 2 && ! Params::Util::_CODELIKE( $_[1] );};
+    return (
+        'if (!defined($_[0]) || $_[0] !~ /^\d+$/) {',
+            $self->_inline_throw_error(
+                '"The n value passed to natatime must be an integer"',
+            ) . ';',
+        '}',
+        'if (@_ == 2 && !Params::Util::_CODELIKE($_[1])) {',
+            $self->_inline_throw_error(
+                '"The second argument passed to natatime must be a code '
+              . 'reference"',
+            ) . ';',
+        '}',
+    );
 }
 
 sub _inline_return_value {
-    my ( $self, $slot_access ) = @_;
-
-    return
-        "my \$iter = List::MoreUtils::natatime( \$_[0], \@{ ($slot_access) } );"
-        . "\n"
-        . 'if ( $_[1] ) {' . "\n"
-        . 'while (my @vals = $iter->()) {' . "\n"
-        . '$_[1]->(@vals);' . "\n" . '}' . "\n"
-        . '} else {' . "\n"
-        . 'return $iter;' . "\n" . '}';
+    my $self = shift;
+    my ($slot_access) = @_;
+
+    return (
+        'my $iter = List::MoreUtils::natatime($_[0], @{ (' . $slot_access . ') });',
+        'if ($_[1]) {',
+            'while (my @vals = $iter->()) {',
+                '$_[1]->(@vals);',
+            '}',
+        '}',
+        'else {',
+            'return $iter;',
+        '}',
+    );
 }
 
 # Not called, but needed to satisfy the Reader role
index 500a448..994e73c 100644 (file)
@@ -23,27 +23,33 @@ sub _maximum_arguments { 0 }
 sub _adds_members { 0 }
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "[ \@{ ($slot_access) } > 1 ? \@{ ($slot_access) }[ 0 .. \$#{ ($slot_access) } - 1 ] : () ]";
+    return '[ @{ (' . $slot_access . ') } > 1 '
+             . '? @{ (' . $slot_access . ') }[0..$#{ (' . $slot_access . ') } - 1] '
+             . ': () ]';
 }
 
 sub _inline_capture_return_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "my \$old = ${slot_access}->[-1];";
+    return 'my $old = ' . $slot_access . '->[-1];';
 }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "pop \@{ ($slot_access) }";
+    return 'pop @{ (' . $slot_access . ') };';
 }
 
 sub _return_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return 'return $old;';
+    return '$old';
 }
 
 no Moose::Role;
index a98e544..7c5b44c 100644 (file)
@@ -21,21 +21,24 @@ with 'Moose::Meta::Method::Accessor::Native::Array::Writer' => {
 sub _adds_members { 1 }
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "[ \@{ ($slot_access) }, \@_ ]";
+    return '[ @{ (' . $slot_access . ') }, @_ ]';
 }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "push \@{ ($slot_access) }, \@_";
+    return 'push @{ (' . $slot_access . ') }, @_;';
 }
 
 sub _return_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "return scalar \@{ ($slot_access) }";
+    return 'scalar @{ (' . $slot_access . ') }';
 }
 
 no Moose::Role;
index f00d3a9..d9cb20c 100644 (file)
@@ -29,16 +29,20 @@ sub _maximum_arguments { 1 }
 sub _inline_check_arguments {
     my $self = shift;
 
-    return $self->_inline_throw_error(
-        q{'The argument passed to reduce must be a code reference'})
-        . q{ unless Params::Util::_CODELIKE( $_[0] );};
+    return (
+        'if (!Params::Util::_CODELIKE($_[0])) {',
+            $self->_inline_throw_error(
+                '"The argument passed to reduce must be a code reference"',
+            ) . ';',
+        '}',
+    );
 }
 
 sub _return_value {
-    my $self        = shift;
-    my $slot_access = shift;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "List::Util::reduce { \$_[0]->( \$a, \$b ) } \@{ ($slot_access) }";
+    return 'List::Util::reduce { $_[0]->($a, $b) } @{ (' . $slot_access . ') }';
 }
 
 no Moose::Role;
index 81cc7d8..6860f10 100644 (file)
@@ -15,6 +15,7 @@ with 'Moose::Meta::Method::Accessor::Native::Array::Writer' => {
             _minimum_arguments
             _maximum_arguments
             _inline_check_arguments
+            _inline_coerce_new_values
             _new_members
             _inline_optimized_set_new_value
             _return_value
@@ -35,37 +36,42 @@ sub _inline_check_arguments {
 sub _adds_members { 1 }
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return
-        "( do { my \@potential = \@{ ($slot_access) }; \$potential[ \$_[0] ] = \$_[1]; \\\@potential } )";
+    return '(do { '
+             . 'my @potential = @{ (' . $slot_access . ') }; '
+             . '$potential[$_[0]] = $_[1]; '
+             . '\@potential; '
+         . '})';
 }
 
 # We need to override this because while @_ can be written to, we cannot write
 # directly to $_[1].
-around _inline_coerce_new_values => sub {
-    shift;
+sub _inline_coerce_new_values {
     my $self = shift;
 
-    return q{} unless $self->associated_attribute->should_coerce;
+    return unless $self->associated_attribute->should_coerce;
 
-    return q{} unless $self->_tc_member_type_can_coerce;
+    return unless $self->_tc_member_type_can_coerce;
 
-    return '@_ = ( $_[0], $member_tc_obj->coerce( $_[1] ) );';
+    return '@_ = ($_[0], $member_tc_obj->coerce($_[1]));';
 };
 
 sub _new_members { '$_[1]' }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "${slot_access}->[ \$_[0] ] = \$_[1]";
+    return $slot_access . '->[$_[0]] = $_[1];';
 }
 
 sub _return_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "return ${slot_access}->[ \$_[0] ];";
+    return $slot_access . '->[$_[0]]';
 }
 
 no Moose::Role;
index 37670b4..e4a0a72 100644 (file)
@@ -25,27 +25,33 @@ sub _maximum_arguments { 0 }
 sub _adds_members { 0 }
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "[ \@{ ($slot_access) } > 1 ? \@{ ($slot_access) }[ 1 .. \$#{ ($slot_access) } ] : () ]";
+    return '[ @{ (' . $slot_access . ') } > 1 '
+             . '? @{ (' . $slot_access . ') }[1..$#{ (' . $slot_access . ') }] '
+             . ': () ]';
 }
 
 sub _inline_capture_return_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "my \$old = ${slot_access}->[0];";
+    return 'my $old = ' . $slot_access . '->[0];';
 }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "shift \@{ ($slot_access) };";
+    return 'shift @{ (' . $slot_access . ') };';
 }
 
 sub _return_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return 'return $old';
+    return '$old';
 }
 
 no Moose::Role;
index 70b3096..cdacd6e 100644 (file)
@@ -17,10 +17,10 @@ with 'Moose::Meta::Method::Accessor::Native::Reader' =>
 sub _maximum_arguments { 0 }
 
 sub _return_value {
-    my $self        = shift;
-    my $slot_access = shift;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "List::Util::shuffle \@{ ($slot_access) }";
+    return 'List::Util::shuffle @{ (' . $slot_access . ') }';
 }
 
 no Moose::Role;
index 60e6520..db109a7 100644 (file)
@@ -25,17 +25,22 @@ sub _maximum_arguments { 1 }
 sub _inline_check_arguments {
     my $self = shift;
 
-    return $self->_inline_throw_error(
-        q{'The argument passed to sort must be a code reference'})
-        . q{ if @_ && ! Params::Util::_CODELIKE( $_[0] );};
+    return (
+        'if (@_ && !Params::Util::_CODELIKE($_[0])) {',
+            $self->_inline_throw_error(
+                '"The argument passed to sort must be a code reference"',
+            ) . ';',
+        '}',
+    );
 }
 
 sub _return_value {
-    my $self        = shift;
-    my $slot_access = shift;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return
-        "\$_[0] ? sort { \$_[0]->( \$a, \$b ) } \@{ ($slot_access) } : sort \@{ ($slot_access) }";
+    return '$_[0] '
+             . '? sort { $_[0]->($a, $b) } @{ (' . $slot_access . ') } '
+             . ': sort @{ (' . $slot_access . ') }';
 }
 
 no Moose::Role;
index dd5f393..83549a8 100644 (file)
@@ -26,21 +26,28 @@ sub _maximum_arguments { 1 }
 sub _inline_check_arguments {
     my $self = shift;
 
-    return $self->_inline_throw_error(
-        q{'The argument passed to sort_in_place must be a code reference'})
-        . q{ if @_ && ! Params::Util::_CODELIKE( $_[0] );};
+    return (
+        'if (@_ && !Params::Util::_CODELIKE($_[0])) {',
+            $self->_inline_throw_error(
+                '"The argument passed to sort_in_place must be a code '
+              . 'reference"',
+            ) . ';',
+        '}',
+    );
 }
 
 sub _adds_members { 0 }
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return
-        "[ \$_[0] ? sort { \$_[0]->( \$a, \$b ) } \@{ ($slot_access) } : sort \@{ ($slot_access) } ]";
+    return '[ $_[0] '
+             . '? sort { $_[0]->($a, $b) } @{ (' . $slot_access . ') } '
+             . ': sort @{ (' . $slot_access . ') } ]';
 }
 
-sub _return_value { return q{} }
+sub _return_value { '' }
 
 no Moose::Role;
 
index f68db7a..967a59e 100644 (file)
@@ -26,35 +26,54 @@ sub _minimum_arguments { 1 }
 sub _adds_members { 1 }
 
 sub _inline_process_arguments {
-    return 'my $idx = shift;' . "\n" . 'my $len = @_ ? shift : undef;';
+    return (
+        'my $idx = shift;',
+        'my $len = @_ ? shift : undef;',
+    );
 }
 
 sub _inline_check_arguments {
     my $self = shift;
 
-    return
-          $self->_inline_check_var_is_valid_index('$idx') . "\n"
-        . $self->_inline_throw_error(q{'The length argument passed to splice must be an integer'})
-        . ' if defined $len && $len !~ /^-?\\d+$/;';
+    return (
+        $self->_inline_check_var_is_valid_index('$idx'),
+        'if (defined($len) && $len !~ /^-?\d+$/) {',
+            $self->_inline_throw_error(
+                '"The length argument passed to splice must be an integer"',
+            ) . ';',
+        '}',
+    );
 }
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
-
-    return "( do { my \@potential = \@{ ($slot_access) };"
-        . '@return = defined $len ? ( splice @potential, $idx, $len, @_ ) : ( splice @potential, $idx ); \\@potential } )';
+    my $self = shift;
+    my ($slot_access) = @_;
+
+    return '(do { '
+             . 'my @potential = @{ (' . $slot_access . ') }; '
+             . '@return = defined $len '
+                 . '? (splice @potential, $idx, $len, @_) '
+                 . ': (splice @potential, $idx); '
+                 . '\@potential;'
+         . '})';
 }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "\@return = defined \$len ? ( splice \@{ ($slot_access) }, \$idx, \$len, \@_ ) : ( splice \@{ ($slot_access) }, \$idx )";
+    return (
+        '@return = defined $len',
+            '? (splice @{ (' . $slot_access . ') }, $idx, $len, @_)',
+            ': (splice @{ (' . $slot_access . ') }, $idx);',
+    );
 }
 
 sub _return_value {
-    my ($self, $slot_access) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return 'return wantarray ? @return : $return[-1]';
+    return 'wantarray ? @return : $return[-1]';
 }
 
 no Moose::Role;
index 9203f52..b49faf8 100644 (file)
@@ -17,10 +17,10 @@ with 'Moose::Meta::Method::Accessor::Native::Reader' =>
 sub _maximum_arguments { 0 }
 
 sub _return_value {
-    my $self        = shift;
-    my $slot_access = shift;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "List::MoreUtils::uniq \@{ ($slot_access) }";
+    return 'List::MoreUtils::uniq @{ (' . $slot_access . ') }';
 }
 
 no Moose::Role;
index 698025d..f545ae2 100644 (file)
@@ -21,21 +21,24 @@ with 'Moose::Meta::Method::Accessor::Native::Array::Writer' => {
 sub _adds_members { 1 }
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "[ \@_, \@{ ($slot_access) } ]";
+    return '[ @_, @{ (' . $slot_access . ') } ]';
 }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "unshift \@{ ($slot_access) }, \@_";
+    return 'unshift @{ (' . $slot_access . ') }, @_;';
 }
 
 sub _return_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "return scalar \@{ ($slot_access) }";
+    return 'scalar @{ (' . $slot_access . ') }';
 }
 
 no Moose::Role;
index 80198bf..f79439b 100644 (file)
@@ -15,9 +15,10 @@ with 'Moose::Meta::Method::Accessor::Native::Reader' =>
 sub _maximum_arguments { 0 }
 
 sub _return_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "! $slot_access";
+    return '!' . $slot_access;
 }
 
 1;
index 6196288..9412cfe 100644 (file)
@@ -23,9 +23,10 @@ sub _maximum_arguments { 0 }
 sub _potential_value { 1 }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "$slot_access = 1";
+    return $slot_access . ' = 1;';
 }
 
 no Moose::Role;
index 6c26131..2e1b711 100644 (file)
@@ -21,15 +21,17 @@ with 'Moose::Meta::Method::Accessor::Native::Writer' => {
 sub _maximum_arguments { 0 }
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "$slot_access ? 0 : 1";
+    return $slot_access . ' ? 0 : 1';
 }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "$slot_access = $slot_access ? 0 : 1";
+    return $slot_access . ' = ' . $slot_access . ' ? 0 : 1;';
 }
 
 no Moose::Role;
index a9d64fb..8d8c7b6 100644 (file)
@@ -23,9 +23,10 @@ sub _maximum_arguments { 0 }
 sub _potential_value { 0 }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "$slot_access = 0";
+    return $slot_access . ' = 0;';
 }
 
 no Moose::Role;
index 390c1ce..38044d3 100644 (file)
@@ -12,9 +12,10 @@ use Moose::Role;
 with 'Moose::Meta::Method::Accessor::Native::Reader';
 
 sub _return_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "${slot_access}->(\@_)";
+    return $slot_access . '->(@_)';
 }
 
 no Moose::Role;
index f17bcc7..c13156b 100644 (file)
@@ -12,9 +12,10 @@ use Moose::Role;
 with 'Moose::Meta::Method::Accessor::Native::Reader';
 
 sub _return_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "${slot_access}->(\$self, \@_)";
+    return $slot_access . '->($self, @_)';
 }
 
 no Moose::Role;
index 1721523..26cf3c5 100644 (file)
@@ -11,20 +11,18 @@ use Moose::Role;
 
 requires qw( _adds_members );
 
-around _inline_coerce_new_values => sub {
-    shift;
+sub _inline_coerce_new_values {
     my $self = shift;
 
-    return q{} unless $self->associated_attribute->should_coerce;
+    return unless $self->associated_attribute->should_coerce;
 
-    return q{} unless $self->_tc_member_type_can_coerce;
+    return unless $self->_tc_member_type_can_coerce;
 
-    return
-          '('
-        . $self->_new_members
-        . ') = map { $member_tc_obj->coerce($_) } '
-        . $self->_new_members . ';';
-};
+    return (
+        '(' . $self->_new_members . ') = map { $member_tc_obj->coerce($_) }',
+                                             $self->_new_members . ';',
+    );
+}
 
 sub _tc_member_type_can_coerce {
     my $self = shift;
@@ -37,43 +35,40 @@ sub _tc_member_type_can_coerce {
 sub _tc_member_type {
     my $self = shift;
 
-    for (
-        my $tc = $self->associated_attribute->type_constraint;
-        $tc;
-        $tc = $tc->parent
-        ) {
-
+    my $tc = $self->associated_attribute->type_constraint;
+    while ($tc) {
         return $tc->type_parameter
             if $tc->can('type_parameter');
+        $tc = $tc->parent;
     }
 
     return;
 }
 
-around _value_needs_copy => sub {
-    shift;
+sub _writer_value_needs_copy {
     my $self = shift;
 
     return $self->_constraint_must_be_checked
         && !$self->_check_new_members_only;
-};
+}
 
-around _inline_tc_code => sub {
-    shift;
-    my ( $self, $potential_value ) = @_;
+sub _inline_tc_code {
+    my $self = shift;
 
-    return q{} unless $self->_constraint_must_be_checked;
+    return unless $self->_constraint_must_be_checked;
 
-    if ( $self->_check_new_members_only ) {
-        return q{} unless $self->_adds_members;
+    if ($self->_check_new_members_only) {
+        return unless $self->_adds_members;
 
-        return $self->_inline_check_member_constraint( $self->_new_members );
+        return $self->_inline_check_member_constraint($self->_new_members);
     }
     else {
-        return $self->_inline_check_coercion($potential_value) . "\n"
-            . $self->_inline_check_constraint($potential_value);
+        return (
+            $self->_inline_check_coercion(@_),
+            $self->_inline_check_constraint(@_),
+        );
     }
-};
+}
 
 sub _check_new_members_only {
     my $self = shift;
@@ -101,31 +96,38 @@ sub _check_new_members_only {
 }
 
 sub _inline_check_member_constraint {
-    my ( $self, $new_value ) = @_;
+    my $self = shift;
+    my ($new_value) = @_;
 
     my $attr_name = $self->associated_attribute->name;
 
-    return '$member_tc->($_) || '
-        . $self->_inline_throw_error(
-        qq{"A new member value for '$attr_name' does not pass its type constraint because: "}
-            . ' . $member_tc_obj->get_message($_)',
-        "data => \$_"
-        ) . " for $new_value;";
+    return (
+        'for (' . $new_value . ') {',
+            'if (!$member_tc->($_)) {',
+                $self->_inline_throw_error(
+                    '"A new member value for ' . $attr_name
+                  . ' does not pass its type constraint because: "'
+                  . ' . $member_tc_obj->get_message($_)',
+                    'data => $_',
+                ) . ';',
+            '}',
+        '}',
+    );
 }
 
-around _inline_get_old_value_for_trigger => sub {
-    shift;
-    my ( $self, $instance ) = @_;
+sub _inline_get_old_value_for_trigger {
+    my $self = shift;
+    my ($instance, $old) = @_;
 
     my $attr = $self->associated_attribute;
-    return '' unless $attr->has_trigger;
+    return unless $attr->has_trigger;
 
-    return
-          'my @old = '
-        . $self->_inline_has($instance) . q{ ? }
-        . $self->_inline_copy_old_value( $self->_inline_get($instance) )
-        . ": ();\n";
-};
+    return (
+        'my ' . $old . ' = ' . $self->_has_value($instance),
+            '? ' . $self->_copy_old_value($self->_get_value($instance)),
+            ': ();',
+    );
+}
 
 around _eval_environment => sub {
     my $orig = shift;
index 2df502c..e01af6a 100644 (file)
@@ -17,8 +17,9 @@ sub _constraint_must_be_checked {
     my $attr = $self->associated_attribute;
 
     return $attr->has_type_constraint
-        && ( $attr->type_constraint->name =~ /^(?:Num|Int)$/
-        || ( $attr->should_coerce && $attr->type_constraint->has_coercion ) );
+        && ($attr->type_constraint->name =~ /^(?:Num|Int)$/
+         || ($attr->should_coerce && $attr->type_constraint->has_coercion)
+           );
 }
 
 no Moose::Role;
index 2870175..feb38db 100644 (file)
@@ -19,19 +19,21 @@ with 'Moose::Meta::Method::Accessor::Native::Writer' => {
     ]
 };
 
-sub _minimum_arguments {0}
-sub _maximum_arguments {1}
+sub _minimum_arguments { 0 }
+sub _maximum_arguments { 1 }
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "$slot_access - ( defined \$_[0] ? \$_[0] : 1 )";
+    return $slot_access . ' - (defined $_[0] ? $_[0] : 1)';
 }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "$slot_access -= defined \$_[0] ? \$_[0] : 1";
+    return $slot_access . ' -= defined $_[0] ? $_[0] : 1;';
 }
 
 no Moose::Role;
index 4db79d4..a07a24a 100644 (file)
@@ -23,15 +23,17 @@ sub _minimum_arguments { 0 }
 sub _maximum_arguments { 1 }
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "$slot_access + ( defined \$_[0] ? \$_[0] : 1 )";
+    return $slot_access . ' + (defined $_[0] ? $_[0] : 1)';
 }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "$slot_access += defined \$_[0] ? \$_[0] : 1";
+    return $slot_access . ' += defined $_[0] ? $_[0] : 1;';
 }
 
 no Moose::Role;
index bf4abd5..510f0dd 100644 (file)
@@ -21,15 +21,17 @@ with 'Moose::Meta::Method::Accessor::Native::Writer' => {
 sub _maximum_arguments { 0 }
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "\$attr->default(\$self)"
+    return '$attr->default($self)';
 }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "$slot_access = \$attr->default(\$self)";
+    return $slot_access . ' = $attr->default($self);';
 }
 
 no Moose::Role;
index 38f84e6..1a32cb3 100644 (file)
@@ -19,15 +19,16 @@ with 'Moose::Meta::Method::Accessor::Native::Writer' => {
     ]
 };
 
-sub _minimum_arguments {1}
-sub _maximum_arguments {1}
+sub _minimum_arguments { 1 }
+sub _maximum_arguments { 1 }
 
-sub _potential_value {'$_[0]'}
+sub _potential_value { '$_[0]' }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "$slot_access = \$_[0];";
+    return $slot_access . ' = $_[0];';
 }
 
 no Moose::Role;
index 814faa1..9d0fda4 100644 (file)
@@ -10,12 +10,17 @@ our $AUTHORITY = 'cpan:STEVAN';
 use Moose::Role;
 
 sub _inline_check_var_is_valid_key {
-    my ( $self, $var ) = @_;
+    my $self = shift;
+    my ($var) = @_;
 
-    return $self->_inline_throw_error( q{'The key passed to }
-            . $self->delegate_to_method
-            . q{ must be a defined value'} )
-        . qq{ unless defined $var;};
+    return (
+        'if (!defined(' . $var . ')) {',
+            $self->_inline_throw_error(
+                '"The key passed to ' . $self->delegate_to_method
+              . ' must be a defined value"',
+            ) . ';',
+        '}',
+    );
 }
 
 no Moose::Role;
index 2602d9a..68147d5 100644 (file)
@@ -11,16 +11,19 @@ our $AUTHORITY = 'cpan:STEVAN';
 
 use Moose::Role;
 
-with 'Moose::Meta::Method::Accessor::Native::Writer',
+with 'Moose::Meta::Method::Accessor::Native::Writer' => {
+        -excludes => ['_inline_coerce_new_values'],
+    },
     'Moose::Meta::Method::Accessor::Native::Hash',
     'Moose::Meta::Method::Accessor::Native::Collection';
 
-sub _new_values {'@values'}
+sub _new_values { '@values' }
 
-sub _inline_copy_old_value {
-    my ( $self, $slot_access ) = @_;
+sub _copy_old_value {
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return '{ %{(' . $slot_access . ')} }';
+    return '{ %{ (' . $slot_access . ') } }';
 }
 
 no Moose::Role;
index 3d9b21e..0e0901a 100644 (file)
@@ -35,47 +35,29 @@ with 'Moose::Meta::Method::Accessor::Native::Hash::set' => {
 sub _generate_method {
     my $self = shift;
 
-    my $inv = '$self';
-
-    my $code = 'sub {';
-    $code .= "\n" . $self->_inline_pre_body(@_);
-
-    $code .= "\n" . 'my $self = shift;';
-
-    $code .= "\n" . $self->_inline_curried_arguments;
-
-    $code .= "\n" . $self->_inline_check_lazy($inv);
-
-    my $slot_access = $self->_inline_get($inv);
-
-    # get
-    $code .= "\n" . 'if ( @_ == 1 ) {';
-
-    $code .= "\n" . $self->_inline_check_var_is_valid_key('$_[0]');
-
-    $code
-        .= "\n"
-        . 'return '
-        . $self
-        ->Moose::Meta::Method::Accessor::Native::Hash::get::_return_value(
-        $slot_access)
-        . ';';
-
-    # set
-    $code .= "\n" . '} else {';
-
-    $code .= "\n" . $self->_writer_core( $inv, $slot_access );
-
-    $code .= "\n" . $self->_inline_post_body(@_);
-
-    $code .= "\n}";
-    $code .= "\n}";
-
-    return $code;
+    my $inv         = '$self';
+    my $slot_access = $self->_get_value($inv);
+
+    return (
+        'sub {',
+            'my ' . $inv . ' = shift;',
+            $self->_inline_curried_arguments,
+            $self->_inline_check_lazy($inv, '$type_constraint', '$type_constraint_obj'),
+            # get
+            'if (@_ == 1) {',
+                $self->_inline_check_var_is_valid_key('$_[0]'),
+                $self->Moose::Meta::Method::Accessor::Native::Hash::get::_inline_return_value($slot_access),
+            '}',
+            # set
+            'else {',
+                $self->_inline_writer_core($inv, $slot_access),
+            '}',
+        '}',
+    );
 }
 
-sub _minimum_arguments {1}
-sub _maximum_arguments {2}
+sub _minimum_arguments { 1 }
+sub _maximum_arguments { 2 }
 
 no Moose::Role;
 
index 52df18f..f2c98c9 100644 (file)
@@ -23,15 +23,16 @@ sub _maximum_arguments { 0 }
 
 sub _adds_members { 0 }
 
-sub _potential_value { return '{}' }
+sub _potential_value { '{}' }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "$slot_access = {}";
+    return $slot_access . ' = {};';
 }
 
-sub _return_value { return q{} }
+sub _return_value { '' }
 
 no Moose::Role;
 
index 7e7d539..8b56c1d 100644 (file)
@@ -17,10 +17,10 @@ with 'Moose::Meta::Method::Accessor::Native::Reader' =>
 sub _maximum_arguments { 0 }
 
 sub _return_value {
-    my $self        = shift;
-    my $slot_access = shift;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "scalar keys \%{ ($slot_access) }";
+    return 'scalar keys %{ (' . $slot_access . ') }';
 }
 
 no Moose::Role;
index 877f19c..667dc21 100644 (file)
@@ -33,10 +33,10 @@ sub _inline_check_arguments {
 }
 
 sub _return_value {
-    my $self        = shift;
-    my $slot_access = shift;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "defined ${slot_access}->{ \$_[0] }";
+    return 'defined ' . $slot_access . '->{ $_[0] }';
 }
 
 no Moose::Role;
index 5c7ae78..5961645 100644 (file)
@@ -21,21 +21,28 @@ with 'Moose::Meta::Method::Accessor::Native::Hash::Writer' => {
 sub _adds_members { 0 }
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
-
-    return "( do { my \%potential = %{ ($slot_access) }; \@return = delete \@potential{\@_}; \\\%potential; } )";
+    my $self = shift;
+    my ($slot_access) = @_;
+
+    return '(do { '
+             . 'my %potential = %{ (' . $slot_access . ') }; '
+             . '@return = delete @potential{@_}; '
+             . '\%potential; '
+         . '})';
 }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "\@return = delete \@{ ($slot_access) }{\@_}";
+    return '@return = delete @{ (' . $slot_access . ') }{@_};';
 }
 
 sub _return_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return 'return wantarray ? @return : $return[-1];';
+    return 'wantarray ? @return : $return[-1]';
 }
 
 no Moose::Role;
index 2913f65..a7beb3a 100644 (file)
@@ -17,10 +17,11 @@ with 'Moose::Meta::Method::Accessor::Native::Reader' =>
 sub _maximum_arguments { 0 }
 
 sub _return_value {
-    my $self        = shift;
-    my $slot_access = shift;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "map { \$_, ${slot_access}->{\$_} } keys \%{ ($slot_access) }";
+    return 'map { $_, ' . $slot_access . '->{$_} } '
+             . 'keys %{ (' . $slot_access . ') }';
 }
 
 no Moose::Role;
index 099786a..64a1662 100644 (file)
@@ -33,10 +33,10 @@ sub _inline_check_arguments {
 }
 
 sub _return_value {
-    my $self        = shift;
-    my $slot_access = shift;
+    my $self = shift;
+    my ($slot_access) = shift;
 
-    return "exists ${slot_access}->{ \$_[0] }";
+    return 'exists ' . $slot_access . '->{ $_[0] }';
 }
 
 no Moose::Role;
index 03d39e7..dabb524 100644 (file)
@@ -26,16 +26,20 @@ sub _minimum_arguments { 1 }
 sub _inline_check_arguments {
     my $self = shift;
 
-    return
-        'for (@_) {' . "\n"
-        . $self->_inline_check_var_is_valid_key('$_') . "\n" . '}';
+    return (
+        'for (@_) {',
+            $self->_inline_check_var_is_valid_key('$_'),
+        '}',
+    );
 }
 
 sub _return_value {
-    my $self        = shift;
-    my $slot_access = shift;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "\@_ > 1 ? \@{ ($slot_access) }{\@_} : ${slot_access}->{ \$_[0] }";
+    return '@_ > 1 '
+             . '? @{ (' . $slot_access . ') }{@_} '
+             . ': ' . $slot_access . '->{$_[0]}';
 }
 
 no Moose::Role;
index c0cfd08..298c74d 100644 (file)
@@ -17,10 +17,10 @@ with 'Moose::Meta::Method::Accessor::Native::Reader' =>
 sub _maximum_arguments { 0 }
 
 sub _return_value {
-    my $self        = shift;
-    my $slot_access = shift;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "scalar keys \%{ ($slot_access) } ? 0 : 1";
+    return 'scalar keys %{ (' . $slot_access . ') } ? 0 : 1';
 }
 
 no Moose::Role;
index 6c16a09..206875e 100644 (file)
@@ -17,10 +17,10 @@ with 'Moose::Meta::Method::Accessor::Native::Reader' =>
 sub _maximum_arguments { 0 }
 
 sub _return_value {
-    my $self        = shift;
-    my $slot_access = shift;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "keys \%{ ($slot_access) }";
+    return 'keys %{ (' . $slot_access . ') }';
 }
 
 no Moose::Role;
index b26132d..f4381c1 100644 (file)
@@ -17,10 +17,11 @@ with 'Moose::Meta::Method::Accessor::Native::Reader' =>
 sub _maximum_arguments { 0 }
 
 sub _return_value {
-    my $self        = shift;
-    my $slot_access = shift;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "map { [ \$_, ${slot_access}->{\$_} ] } keys \%{ ($slot_access) }";
+    return 'map { [ $_, ' . $slot_access . '->{$_} ] } '
+             . 'keys %{ (' . $slot_access . ') }';
 }
 
 no Moose::Role;
index e0cdbc8..f948d9f 100644 (file)
@@ -19,6 +19,7 @@ with 'Moose::Meta::Method::Accessor::Native::Hash::Writer' => {
             _maximum_arguments
             _inline_process_arguments
             _inline_check_arguments
+            _inline_coerce_new_values
             _inline_optimized_set_new_value
             _return_value
             )
@@ -33,68 +34,83 @@ around _inline_check_argument_count => sub {
     my $orig = shift;
     my $self = shift;
 
-    return
-        $self->$orig(@_) . "\n"
-        . $self->_inline_throw_error(
-        q{'You must pass an even number of arguments to set'})
-        . ' if @_ % 2;';
+    return (
+        $self->$orig(@_),
+        'if (@_ % 2) {',
+            $self->_inline_throw_error(
+                '"You must pass an even number of arguments to set"',
+            ) . ';',
+        '}',
+    );
 };
 
 sub _inline_process_arguments {
     my $self = shift;
 
-    return 'my @keys_idx = grep { ! ($_ % 2) } 0..$#_;' . "\n"
-        . 'my @values_idx = grep { $_ % 2 } 0..$#_;';
+    return (
+        'my @keys_idx = grep { ! ($_ % 2) } 0..$#_;',
+        'my @values_idx = grep { $_ % 2 } 0..$#_;',
+    );
 }
 
 sub _inline_check_arguments {
     my $self = shift;
 
-    return
-        'for (@keys_idx) {' . "\n"
-        . $self->_inline_throw_error(
-        q{'Hash keys passed to set must be defined'})
-        . ' unless defined $_[$_];' . "\n" . '}';
+    return (
+        'for (@keys_idx) {',
+            'if (!defined($_[$_])) {',
+                $self->_inline_throw_error(
+                    '"Hash keys passed to set must be defined"',
+                ) . ';',
+            '}',
+        '}',
+    );
 }
 
 sub _adds_members { 1 }
 
 # We need to override this because while @_ can be written to, we cannot write
 # directly to $_[1].
-around _inline_coerce_new_values => sub {
-    shift;
+sub _inline_coerce_new_values {
     my $self = shift;
 
-    return q{} unless $self->associated_attribute->should_coerce;
+    return unless $self->associated_attribute->should_coerce;
 
-    return q{} unless $self->_tc_member_type_can_coerce;
+    return unless $self->_tc_member_type_can_coerce;
 
     # Is there a simpler way to do this?
-    return 'my $iter = List::MoreUtils::natatime 2, @_;'
-         .  '@_ = ();'
-         . 'while ( my ( $key, $val ) = $iter->() ) {'
-         .     'push @_, $key, $member_tc_obj->coerce($val);'
-         . '}';
+    return (
+        'my $iter = List::MoreUtils::natatime(2, @_);',
+        '@_ = ();',
+        'while (my ($key, $val) = $iter->()) {',
+            'push @_, $key, $member_tc_obj->coerce($val);',
+        '}',
+    );
 };
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "{ %{ ($slot_access) }, \@_ }";
+    return '{ %{ (' . $slot_access . ') }, @_ }';
 }
 
 sub _new_members { '@_[ @values_idx ]' }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "\@{ ($slot_access) }{ \@_[ \@keys_idx] } = \@_[ \@values_idx ]";
+    return '@{ (' . $slot_access . ') }{ @_[@keys_idx] } = @_[@values_idx];';
 }
 
 sub _return_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "return wantarray ? \@{ ($slot_access) }{ \@_[ \@keys_idx ] } : ${slot_access}->{ \$_[ \$keys_idx[0] ] };";
+    return 'wantarray '
+             . '? @{ (' . $slot_access . ') }{ @_[@keys_idx] } '
+             . ': ' . $slot_access . '->{ $_[$keys_idx[0]] }';
 }
 
 no Moose::Role;
index ab234e5..7ac72e2 100644 (file)
@@ -17,10 +17,10 @@ with 'Moose::Meta::Method::Accessor::Native::Reader' =>
 sub _maximum_arguments { 0 }
 
 sub _return_value {
-    my $self        = shift;
-    my $slot_access = shift;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "values \%{ ($slot_access) }";
+    return 'values %{ (' . $slot_access . ') }';
 }
 
 no Moose::Role;
index 0784948..5468cc5 100644 (file)
@@ -18,18 +18,20 @@ with 'Moose::Meta::Method::Accessor::Native::Writer' => {
     ]
     };
 
-sub _maximum_arguments {0}
+sub _maximum_arguments { 0 }
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "abs($slot_access)";
+    return 'abs(' . $slot_access . ')';
 }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "$slot_access = abs($slot_access)";
+    return $slot_access . ' = abs(' . $slot_access . ');';
 }
 
 no Moose::Role;
index 6ce3613..4db6f81 100644 (file)
@@ -19,20 +19,22 @@ with 'Moose::Meta::Method::Accessor::Native::Writer' => {
     ]
     };
 
-sub _minimum_arguments {1}
+sub _minimum_arguments { 1 }
 
-sub _maximum_arguments {1}
+sub _maximum_arguments { 1 }
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "$slot_access + \$_[0]";
+    return $slot_access . ' + $_[0]';
 }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "$slot_access += \$_[0]";
+    return $slot_access . ' += $_[0];';
 }
 
 no Moose::Role;
index a42125f..2238917 100644 (file)
@@ -19,20 +19,22 @@ with 'Moose::Meta::Method::Accessor::Native::Writer' => {
     ]
     };
 
-sub _minimum_arguments {1}
+sub _minimum_arguments { 1 }
 
-sub _maximum_arguments {1}
+sub _maximum_arguments { 1 }
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "$slot_access / \$_[0]";
+    return $slot_access . ' / $_[0]';
 }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "$slot_access /= \$_[0]";
+    return $slot_access . ' /= $_[0];';
 }
 
 no Moose::Role;
index fbbb434..e9022f8 100644 (file)
@@ -19,20 +19,22 @@ with 'Moose::Meta::Method::Accessor::Native::Writer' => {
     ]
     };
 
-sub _minimum_arguments {1}
+sub _minimum_arguments { 1 }
 
-sub _maximum_arguments {1}
+sub _maximum_arguments { 1 }
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "$slot_access % \$_[0]";
+    return $slot_access . ' % $_[0]';
 }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "$slot_access %= \$_[0]";
+    return $slot_access . ' %= $_[0];';
 }
 
 no Moose::Role;
index b6d59a5..643f148 100644 (file)
@@ -19,20 +19,22 @@ with 'Moose::Meta::Method::Accessor::Native::Writer' => {
     ]
     };
 
-sub _minimum_arguments {1}
+sub _minimum_arguments { 1 }
 
-sub _maximum_arguments {1}
+sub _maximum_arguments { 1 }
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "$slot_access * \$_[0]";
+    return $slot_access . ' * $_[0]';
 }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "$slot_access *= \$_[0]";
+    return $slot_access . ' *= $_[0];';
 }
 
 no Moose::Role;
index 263e1e6..3d8c642 100644 (file)
@@ -19,15 +19,16 @@ with 'Moose::Meta::Method::Accessor::Native::Writer' => {
     ]
     };
 
-sub _minimum_arguments {1}
-sub _maximum_arguments {1}
+sub _minimum_arguments { 1 }
+sub _maximum_arguments { 1 }
 
-sub _potential_value {'$_[0]'}
+sub _potential_value { '$_[0]' }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "$slot_access = \$_[0]";
+    return $slot_access . ' = $_[0];';
 }
 
 no Moose::Role;
index e75ca69..30d5d13 100644 (file)
@@ -19,20 +19,22 @@ with 'Moose::Meta::Method::Accessor::Native::Writer' => {
     ]
     };
 
-sub _minimum_arguments {1}
+sub _minimum_arguments { 1 }
 
-sub _maximum_arguments {1}
+sub _maximum_arguments { 1 }
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "$slot_access - \$_[0]";
+    return $slot_access . ' - $_[0]';
 }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "$slot_access -= \$_[0]";
+    return $slot_access . ' -= $_[0];';
 }
 
 no Moose::Role;
index 957207c..564e4da 100644 (file)
@@ -16,49 +16,34 @@ requires '_return_value';
 sub _generate_method {
     my $self = shift;
 
-    my $inv = '$self';
-
-    my $code = 'sub {';
-    $code .= "\n" . $self->_inline_pre_body(@_);
-
-    $code .= "\n" . 'my $self = shift;';
-
-    $code .= "\n" . $self->_inline_curried_arguments;
-
-    my $slot_access = $self->_inline_get($inv);
-
-    $code .= "\n" . $self->_reader_core( $inv, $slot_access, @_ );
-
-    $code .= "\n}";
-
-    return $code;
+    my $inv         = '$self';
+    my $slot_access = $self->_get_value($inv);
+
+    return (
+        'sub {',
+            'my ' . $inv . ' = shift;',
+            $self->_inline_curried_arguments,
+            $self->_inline_reader_core($inv, $slot_access, @_),
+        '}',
+    );
 }
 
-sub _reader_core {
-    my ( $self, $inv, $slot_access, @extra ) = @_;
-
-    my $code = q{};
-
-    $code .= "\n" . $self->_inline_check_argument_count;
-    $code .= "\n" . $self->_inline_process_arguments( $inv, $slot_access );
-    $code .= "\n" . $self->_inline_check_arguments;
-
-    $code .= "\n" . $self->_inline_check_lazy($inv);
-    $code .= "\n" . $self->_inline_post_body(@extra);
-    $code .= "\n" . $self->_inline_return_value($slot_access);
-
-    return $code;
+sub _inline_reader_core {
+    my $self = shift;
+    my ($inv, $slot_access, @extra) = @_;
+
+    return (
+        $self->_inline_check_argument_count,
+        $self->_inline_process_arguments($inv, $slot_access),
+        $self->_inline_check_arguments,
+        $self->_inline_check_lazy($inv, '$type_constraint', '$type_constraint_obj'),
+        $self->_inline_return_value($slot_access),
+    );
 }
 
-sub _inline_process_arguments {q{}}
+sub _inline_process_arguments { return }
 
-sub _inline_check_arguments {q{}}
-
-sub _inline_return_value {
-    my ( $self, $slot_access ) = @_;
-
-    'return ' . $self->_return_value($slot_access) . ';';
-}
+sub _inline_check_arguments { return }
 
 no Moose::Role;
 
index 51df675..e20b168 100644 (file)
@@ -24,15 +24,17 @@ sub _minimum_arguments { 1 }
 sub _maximum_arguments { 1 }
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "( $slot_access . \$_[0] )";
+    return '( ' . $slot_access . ' . $_[0] )';
 }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "$slot_access .= \$_[0]";
+    return $slot_access . ' .= $_[0];';
 }
 
 no Moose::Role;
index 1dc33cd..6173952 100644 (file)
@@ -19,22 +19,29 @@ with 'Moose::Meta::Method::Accessor::Native::Writer' => {
     ]
 };
 
-sub _maximum_arguments {0}
+sub _maximum_arguments { 0 }
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
-
-    return "( do { my \$val = $slot_access; \@return = chomp \$val; \$val } )";
+    my $self = shift;
+    my ($slot_access) = @_;
+
+    return '(do { '
+             . 'my $val = ' . $slot_access . '; '
+             . '@return = chomp $val; '
+             . '$val '
+         . '})';
 }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "\@return = chomp $slot_access";
+    return '@return = chomp ' . $slot_access . ';';
 }
 
 sub _return_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
     return '$return[0]';
 }
index f8784d0..c2db357 100644 (file)
@@ -22,19 +22,26 @@ with 'Moose::Meta::Method::Accessor::Native::Writer' => {
 sub _maximum_arguments { 0 }
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
-
-    return "( do { my \$val = $slot_access; \@return = chop \$val; \$val } )";
+    my $self = shift;
+    my ($slot_access) = @_;
+
+    return '(do { '
+             . 'my $val = ' . $slot_access . '; '
+             . '@return = chop $val; '
+             . '$val; '
+         . '})';
 }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "\@return = chop $slot_access";
+    return '@return = chop ' . $slot_access . ';';
 }
 
 sub _return_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
     return '$return[0]';
 }
index f47c788..fd7645e 100644 (file)
@@ -20,16 +20,13 @@ with 'Moose::Meta::Method::Accessor::Native::Writer' => {
 
 sub _maximum_arguments { 0 }
 
-sub _potential_value {
-    my ( $self, $slot_access ) = @_;
-
-    return "q{}";
-}
+sub _potential_value { '""' }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "$slot_access = q{}";
+    return $slot_access . ' = "";';
 }
 
 no Moose::Role;
index 595ade8..627d243 100644 (file)
@@ -21,15 +21,21 @@ with 'Moose::Meta::Method::Accessor::Native::Writer' => {
 sub _maximum_arguments { 0 }
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
-
-    return "( do { my \$val = $slot_access; \$val++; \$val } )";
+    my $self = shift;
+    my ($slot_access) = @_;
+
+    return '(do { '
+             . 'my $val = ' . $slot_access . '; '
+             . '$val++; '
+             . '$val; '
+         . '})';
 }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "${slot_access}++";
+    return $slot_access . '++;';
 }
 
 no Moose::Role;
index c0749a9..3fc8686 100644 (file)
@@ -15,9 +15,10 @@ with 'Moose::Meta::Method::Accessor::Native::Reader' =>
 sub _maximum_arguments { 0 }
 
 sub _return_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "length $slot_access";
+    return 'length ' . $slot_access;
 }
 
 no Moose::Role;
index 989776e..950b7df 100644 (file)
@@ -29,15 +29,21 @@ sub _maximum_arguments { 1 }
 sub _inline_check_arguments {
     my $self = shift;
 
-    return $self->_inline_throw_error(
-        q{'The argument passed to match must be a string or regexp reference'}
-    ) . q{ unless Moose::Util::_STRINGLIKE0( $_[0] ) || Params::Util::_REGEX( $_[0] );};
+    return (
+        'if (!Moose::Util::_STRINGLIKE0($_[0]) && !Params::Util::_REGEX($_[0])) {',
+            $self->_inline_throw_error(
+                '"The argument passed to match must be a string or regexp '
+              . 'reference"',
+            ) . ';',
+        '}',
+    );
 }
 
 sub _return_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "$slot_access =~ \$_[0]";
+    return $slot_access . ' =~ $_[0]';
 }
 
 no Moose::Role;
index 5f77cdd..15829d3 100644 (file)
@@ -24,15 +24,17 @@ sub _minimum_arguments { 1 }
 sub _maximum_arguments { 1 }
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "( \$_[0] . $slot_access )";
+    return '$_[0] . ' . $slot_access;
 }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "$slot_access = \$_[0] . $slot_access";
+    return $slot_access . ' = $_[0] . ' . $slot_access . ';';
 }
 
 no Moose::Role;
index 4098509..25b0c71 100644 (file)
@@ -30,25 +30,44 @@ sub _maximum_arguments { 2 }
 sub _inline_check_arguments {
     my $self = shift;
 
-    return $self->_inline_throw_error(
-        q{'The first argument passed to replace must be a string or regexp reference'}
-        )
-        . q{ unless Moose::Util::_STRINGLIKE0( $_[0] ) || Params::Util::_REGEX( $_[0] );}
-        . $self->_inline_throw_error(
-        q{'The second argument passed to replace must be a string or code reference'}
-        ) . q{ unless Moose::Util::_STRINGLIKE0( $_[1] ) || Params::Util::_CODELIKE( $_[1] );};
+    return (
+        'if (!Moose::Util::_STRINGLIKE0($_[0]) && !Params::Util::_REGEX($_[0])) {',
+            $self->_inline_throw_error(
+                '"The first argument passed to replace must be a string or '
+              . 'regexp reference"'
+            ) . ';',
+        '}',
+        'if (!Moose::Util::_STRINGLIKE0($_[1]) && !Params::Util::_CODELIKE($_[1])) {',
+            $self->_inline_throw_error(
+                '"The second argument passed to replace must be a string or '
+              . 'code reference"'
+            ) . ';',
+        '}',
+    );
 }
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return "( do { my \$val = $slot_access; ref \$_[1] ? \$val =~ s/\$_[0]/\$_[1]->()/e : \$val =~ s/\$_[0]/\$_[1]/; \$val } )";
+    return '(do { '
+             . 'my $val = ' . $slot_access . '; '
+             . 'ref $_[1] '
+                 . '? $val =~ s/$_[0]/$_[1]->()/e '
+                 . ': $val =~ s/$_[0]/$_[1]/; '
+             . '$val; '
+         . '})';
 }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "if ( ref \$_[1] ) { $slot_access =~ s/\$_[0]/\$_[1]->()/e; } else { $slot_access =~ s/\$_[0]/\$_[1]/; }";
+    return (
+        'ref $_[1]',
+            '? ' . $slot_access . ' =~ s/$_[0]/$_[1]->()/e',
+            ': ' . $slot_access . ' =~ s/$_[0]/$_[1]/;',
+     );
 }
 
 no Moose::Role;
index e4f1c13..61d7fbf 100644 (file)
@@ -39,90 +39,96 @@ with 'Moose::Meta::Method::Accessor::Native::Reader' => {
 sub _generate_method {
     my $self = shift;
 
-    my $inv = '$self';
-
-    my $slot_access = $self->_inline_get($inv);
-
-    my $code = 'sub {';
-
-    $code .= "\n" . $self->_inline_pre_body(@_);
-    $code .= "\n" . 'my $self = shift;';
-
-    $code .= "\n" . $self->_inline_curried_arguments;
-
-    $code .= "\n" . 'if ( @_ == 1 || @_ == 2 ) {';
-
-    $code .= $self->_reader_core( $inv, $slot_access );
-
-    $code .= "\n" . '} elsif ( @_ == 3 ) {';
-
-    $code .= $self->_writer_core( $inv, $slot_access );
-
-    $code .= "\n" . $self->_inline_post_body(@_);
-
-    $code .= "\n" . '} else {';
-
-    $code .= "\n" . $self->_inline_check_argument_count;
-
-    $code .= "\n" . '}';
-    $code .= "\n" . '}';
-
-    return $code;
+    my $inv         = '$self';
+    my $slot_access = $self->_get_value($inv);
+
+    return (
+        'sub {',
+            'my ' . $inv . ' = shift;',
+            $self->_inline_curried_arguments,
+            'if (@_ == 1 || @_ == 2) {',
+                $self->_inline_reader_core($inv, $slot_access),
+            '}',
+            'elsif (@_ == 3) {',
+                $self->_inline_writer_core($inv, $slot_access),
+            '}',
+            'else {',
+                $self->_inline_check_argument_count,
+            '}',
+        '}',
+    );
 }
 
-sub _minimum_arguments {1}
-sub _maximum_arguments {3}
+sub _minimum_arguments { 1 }
+sub _maximum_arguments { 3 }
 
 sub _inline_process_arguments {
-    my ( $self, $inv, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $slot_access) = @_;
 
-    return
-          'my $offset = shift;' . "\n"
-        . "my \$length = \@_ ? shift : length $slot_access;" . "\n"
-        . 'my $replacement = shift;';
+    return (
+        'my $offset = shift;',
+        'my $length = @_ ? shift : length ' . $slot_access . ';',
+        'my $replacement = shift;',
+    );
 }
 
 sub _inline_check_arguments {
-    my ( $self, $for_writer ) = @_;
-
-    my $code
-        = $self->_inline_throw_error(
-        q{'The first argument passed to substr must be an integer'})
-        . q{ unless $offset =~ /^-?\\d+$/;} . "\n"
-        . $self->_inline_throw_error(
-        q{'The second argument passed to substr must be an integer'})
-        . q{ unless $length =~ /^-?\\d+$/;};
+    my $self = shift;
+    my ($for_writer) = @_;
+
+    my @code = (
+        'if ($offset !~ /^-?\d+$/) {',
+            $self->_inline_throw_error(
+                '"The first argument passed to substr must be an integer"'
+            ) . ';',
+        '}',
+        'if ($length !~ /^-?\d+$/) {',
+            $self->_inline_throw_error(
+                '"The second argument passed to substr must be an integer"'
+            ) . ';',
+        '}',
+    );
 
     if ($for_writer) {
-        $code
-            .= "\n"
-            . $self->_inline_throw_error(
-            q{'The third argument passed to substr must be a string'})
-            . q{ unless Moose::Util::_STRINGLIKE0($replacement);};
+        push @code, (
+            'if (!Moose::Util::_STRINGLIKE0($replacement)) {',
+                $self->_inline_throw_error(
+                    '"The third argument passed to substr must be a string"'
+                ) . ';',
+            '}',
+        );
     }
 
-    return $code;
+    return @code;
 }
 
 sub _potential_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
-    return
-        "( do { my \$potential = $slot_access; \@return = substr \$potential, \$offset, \$length, \$replacement; \$potential; } )";
+    return '(do { '
+             . 'my $potential = ' . $slot_access . '; '
+             . '@return = substr $potential, $offset, $length, $replacement; '
+             . '$potential; '
+         . '})';
 }
 
 sub _inline_optimized_set_new_value {
-    my ( $self, $inv, $new, $slot_access ) = @_;
+    my $self = shift;
+    my ($inv, $new, $slot_access) = @_;
 
-    return "\@return = substr $slot_access, \$offset, \$length, \$replacement";
+    return '@return = substr ' . $slot_access . ', '
+                           . '$offset, $length, $replacement;';
 }
 
 sub _return_value {
-    my ( $self, $slot_access, $for_writer ) = @_;
+    my $self = shift;
+    my ($slot_access, $for_writer) = @_;
 
     return '$return[0]' if $for_writer;
 
-    return "substr $slot_access, \$offset, \$length";
+    return 'substr ' . $slot_access . ', $offset, $length';
 }
 
 no Moose::Role;
index 85af7b2..12230ca 100644 (file)
@@ -18,75 +18,60 @@ requires '_potential_value';
 sub _generate_method {
     my $self = shift;
 
-    my $inv = '$self';
-
-    my $slot_access = $self->_inline_get($inv);
-
-    my $code = 'sub {';
-
-    $code .= "\n" . $self->_inline_pre_body(@_);
-
-    $code .= "\n" . 'my $self = shift;';
-
-    $code .= "\n" . $self->_inline_curried_arguments;
-
-    $code .= $self->_writer_core( $inv, $slot_access );
-
-    $code .= "\n" . $self->_inline_post_body(@_);
-
-    $code .= "\n}";
-
-    return $code;
+    my $inv         = '$self';
+    my $slot_access = $self->_get_value($inv);
+
+    return (
+        'sub {',
+            'my ' . $inv . ' = shift;',
+            $self->_inline_curried_arguments,
+            $self->_inline_writer_core($inv, $slot_access),
+        '}',
+    );
 }
 
-sub _writer_core {
-    my ( $self, $inv, $slot_access ) = @_;
-
-    my $code = q{};
-
-    $code .= "\n" . $self->_inline_check_argument_count;
-    $code .= "\n" . $self->_inline_process_arguments( $inv, $slot_access );
-    $code .= "\n" . $self->_inline_check_arguments('for writer');
+sub _inline_writer_core {
+    my $self = shift;
+    my ($inv, $slot_access) = @_;
 
-    $code .= "\n" . $self->_inline_check_lazy($inv);
+    my $potential = $self->_potential_value($slot_access);
+    my $old       = '@old';
 
-    my $potential_value = $self->_potential_value($slot_access);
+    my @code;
+    push @code, (
+        $self->_inline_check_argument_count,
+        $self->_inline_process_arguments($inv, $slot_access),
+        $self->_inline_check_arguments('for writer'),
+        $self->_inline_check_lazy($inv, '$type_constraint', '$type_constraint_obj'),
+    );
 
-    if ( $self->_return_value($slot_access) ) {
+    if ($self->_return_value($slot_access)) {
         # some writers will save the return value in this variable when they
         # generate the potential value.
-        $code .= "\n" . 'my @return;';
+        push @code, 'my @return;'
     }
 
-    # This is only needed by collections.
-    $code .= "\n" . $self->_inline_coerce_new_values;
-    $code .= "\n" . $self->_inline_copy_native_value( \$potential_value );
-    $code .= "\n"
-        . $self->_inline_tc_code(
-        $potential_value
-        );
-
-    $code .= "\n" . $self->_inline_get_old_value_for_trigger($inv);
-    $code .= "\n" . $self->_inline_capture_return_value($slot_access);
-    $code .= "\n"
-        . $self->_inline_set_new_value(
-        $inv,
-        $potential_value,
-        $slot_access,
-        ) . ';';
-    $code .= "\n" . $self->_inline_trigger( $inv, $slot_access, '@old' );
-    $code .= "\n" . $self->_return_value( $slot_access, 'for writer' );
-
-    return $code;
+    push @code, (
+        $self->_inline_coerce_new_values,
+        $self->_inline_copy_native_value(\$potential),
+        $self->_inline_tc_code($potential, '$type_constraint', '$type_constraint_obj'),
+        $self->_inline_get_old_value_for_trigger($inv, $old),
+        $self->_inline_capture_return_value($slot_access),
+        $self->_inline_set_new_value($inv, $potential, $slot_access),
+        $self->_inline_trigger($inv, $slot_access, $old),
+        $self->_inline_return_value($slot_access, 'for writer'),
+    );
+
+    return @code;
 }
 
-sub _inline_process_arguments {q{}}
+sub _inline_process_arguments { return }
 
-sub _inline_check_arguments {q{}}
+sub _inline_check_arguments { return }
 
-sub _inline_coerce_new_values {q{}}
+sub _inline_coerce_new_values { return }
 
-sub _value_needs_copy {
+sub _writer_value_needs_copy {
     my $self = shift;
 
     return $self->_constraint_must_be_checked;
@@ -98,75 +83,79 @@ sub _constraint_must_be_checked {
     my $attr = $self->associated_attribute;
 
     return $attr->has_type_constraint
-        && ( !$self->_is_root_type( $attr->type_constraint )
-        || ( $attr->should_coerce && $attr->type_constraint->has_coercion ) );
+        && (!$self->_is_root_type( $attr->type_constraint )
+         || ( $attr->should_coerce && $attr->type_constraint->has_coercion)
+           );
 }
 
 sub _is_root_type {
-    my ($self, $type) = @_;
+    my $self = shift;
+    my ($type) = @_;
 
-    my $name = $type->name();
+    my $name = $type->name;
 
     return any { $name eq $_ } @{ $self->root_types };
 }
 
 sub _inline_copy_native_value {
-    my ( $self, $potential_ref ) = @_;
+    my $self = shift;
+    my ($potential_ref) = @_;
 
-    return q{} unless $self->_value_needs_copy;
+    return unless $self->_writer_value_needs_copy;
 
-    my $code = "my \$potential = ${$potential_ref};";
+    my $code = 'my $potential = ' . ${$potential_ref} . ';';
 
     ${$potential_ref} = '$potential';
 
     return $code;
 }
 
-sub _inline_tc_code {
-    my ( $self, $potential_value ) = @_;
+around _inline_tc_code => sub {
+    my $orig = shift;
+    my $self = shift;
+    my ($value, $tc, $tc_obj, $for_lazy) = @_;
 
-    return q{} unless $self->_constraint_must_be_checked;
+    return unless $for_lazy || $self->_constraint_must_be_checked;
 
-    return $self->_inline_check_coercion($potential_value) . "\n"
-        . $self->_inline_check_constraint($potential_value);
-}
+    return $self->$orig(@_);
+};
 
 sub _inline_check_coercion {
-    my ( $self, $value ) = @_;
+    my $self = shift;
+    my ($value, $tc, $tc_obj) = @_;
 
     my $attr = $self->associated_attribute;
-
-    return q{}
-        unless $attr->should_coerce
-            && $attr->type_constraint->has_coercion;
+    return unless $attr->should_coerce && $attr->type_constraint->has_coercion;
 
     # We want to break the aliasing in @_ in case the coercion tries to make a
     # destructive change to an array member.
-    return "$value = \$type_constraint_obj->coerce($value);";
+    return $value . ' = ' . $tc_obj . '->coerce(' . $value . ');';
 }
 
-override _inline_check_constraint => sub {
-    my ( $self, $value, $for_lazy ) = @_;
+around _inline_check_constraint => sub {
+    my $orig = shift;
+    my $self = shift;
+    my ($value, $tc, $tc_obj, $for_lazy) = @_;
 
-    return q{} unless $for_lazy || $self->_constraint_must_be_checked;
+    return unless $for_lazy || $self->_constraint_must_be_checked;
 
-    return super();
+    return $self->$orig(@_);
 };
 
-sub _inline_capture_return_value { return q{} }
+sub _inline_capture_return_value { return }
 
 sub _inline_set_new_value {
     my $self = shift;
 
-    return $self->_inline_store(@_)
-        if $self->_value_needs_copy
+    return $self->_inline_store_value(@_)
+        if $self->_writer_value_needs_copy
         || !$self->_slot_access_can_be_inlined
-        || !$self->_inline_get_is_lvalue;
+        || !$self->_get_is_lvalue;
 
     return $self->_inline_optimized_set_new_value(@_);
 }
 
-sub _inline_get_is_lvalue {
+sub _get_is_lvalue {
     my $self = shift;
 
     return $self->associated_attribute->associated_class->instance_metaclass->inline_get_is_lvalue;
@@ -175,11 +164,12 @@ sub _inline_get_is_lvalue {
 sub _inline_optimized_set_new_value {
     my $self = shift;
 
-    return $self->_inline_store(@_);
+    return $self->_inline_store_value(@_);
 }
 
 sub _return_value {
-    my ( $self, $slot_access ) = @_;
+    my $self = shift;
+    my ($slot_access) = @_;
 
     return $slot_access;
 }
index c1af28d..065482f 100644 (file)
@@ -6,6 +6,7 @@ use warnings;
 
 use Carp ();
 use Scalar::Util 'blessed', 'weaken', 'looks_like_number', 'refaddr';
+use Try::Tiny;
 
 our $VERSION   = '1.19';
 our $AUTHORITY = 'cpan:STEVAN';
@@ -48,34 +49,15 @@ sub new {
 
 sub _initialize_body {
     my $self = shift;
-    # TODO:
-    # the %options should also include a both
-    # a call 'initializer' and call 'SUPER::'
-    # options, which should cover approx 90%
-    # of the possible use cases (even if it
-    # requires some adaption on the part of
-    # the author, after all, nothing is free)
-    my $source = 'sub {';
-    $source .= "\n" . 'my $_instance = shift;';
-
-    $source .= "\n" . 'my $class = Scalar::Util::blessed($_instance) || $_instance;';
-
-    $source .= "\n" . "if (\$class ne '" . $self->associated_metaclass->name
-            .  "') {";
-    $source .= "\n    return "
-            .  $self->_generate_fallback_constructor('$class') . ";";
-    $source .= "\n}\n";
-
-    $source .= $self->_generate_params('$params', '$class');
-    $source .= $self->_generate_instance('$instance', '$class');
-    $source .= $self->_generate_slot_initializers;
-
-    $source .= $self->_generate_triggers();
-    $source .= ";\n" . $self->_generate_BUILDALL();
-
-    $source .= ";\nreturn \$instance";
-    $source .= ";\n" . '}';
-    warn $source if $self->options->{debug};
+    $self->{'body'} = $self->_generate_constructor_method_inline;
+}
+
+sub _eval_environment {
+    my $self = shift;
+
+    my $attrs = $self->_attributes;
+
+    my $defaults = [map { $_->default } @$attrs];
 
     # We need to check if the attribute ->can('type_constraint')
     # since we may be trying to immutabilize a Moose meta class,
@@ -86,8 +68,6 @@ sub _initialize_body {
     # because the inlined code is using the index of the attributes
     # to determine where to find the type constraint
 
-    my $attrs = $self->_attributes;
-
     my @type_constraints = map {
         $_->can('type_constraint') ? $_->type_constraint : undef
     } @$attrs;
@@ -96,255 +76,13 @@ sub _initialize_body {
         defined $_ ? $_->_compiled_type_constraint : undef;
     } @type_constraints;
 
-    my $defaults = [map { $_->default } @$attrs];
-
-    my ( $code, $e ) = $self->_compile_code(
-        code => $source,
-        environment => {
-            '$meta'  => \$self,
-            '$attrs' => \$attrs,
-            '$defaults' => \$defaults,
-            '@type_constraints' => \@type_constraints,
-            '@type_constraint_bodies' => \@type_constraint_bodies,
-        },
-    );
-
-    $self->throw_error(
-        "Could not eval the constructor :\n\n$source\n\nbecause :\n\n$e",
-        error => $e, data => $source )
-        if $e;
-
-    $self->{'body'} = $code;
-}
-
-sub _generate_fallback_constructor {
-    my ( $self, $class_var ) = @_;
-    "${class_var}->Moose::Object::new(\@_)";
-}
-
-sub _generate_params {
-    my ( $self, $var, $class_var ) = @_;
-    "my $var = " . $self->_generate_BUILDARGS( $class_var, '@_' ) . ";\n";
-}
-
-sub _generate_instance {
-    my ( $self, $var, $class_var ) = @_;
-    "my $var = "
-        . $self->associated_metaclass->inline_create_instance($class_var) . ";\n";
-}
-
-sub _generate_slot_initializers {
-    my ($self) = @_;
-    return (join ";\n" => map {
-        $self->_generate_slot_initializer($_)
-    } 0 .. (@{$self->_attributes} - 1)) . ";\n";
-}
-
-sub _generate_BUILDARGS {
-    my ( $self, $class, $args ) = @_;
-
-    my $buildargs = $self->associated_metaclass->find_method_by_name("BUILDARGS");
-
-    if ( $args eq '@_'
-        and ( !$buildargs or $buildargs->body == \&Moose::Object::BUILDARGS )
-        ) {
-
-        # This is the same logic as Moose::Object::BUILDARGS
-        return sprintf( <<'EOF', $self->_inline_throw_error( q{'Single parameters to new() must be a HASH ref'}, 'data => $_[0]' ) );
-do {
-    my $params;
-    if ( scalar @_ == 1 ) {
-        unless ( defined $_[0] && ref $_[0] eq 'HASH' ) {
-            %s
-        }
-        $params = { %%{ $_[0] } };
-    }
-    elsif ( @_ %% 2 ) {
-        Carp::carp(
-            "The new() method for $class expects a hash reference or a key/value list."
-                . " You passed an odd number of arguments" );
-        $params = { @_, undef };
-    }
-    else {
-        $params = {@_};
-    }
-    $params
-};
-EOF
-            ;
-    }
-    else {
-        return $class . "->BUILDARGS($args)";
-    }
-}
-
-sub _generate_BUILDALL {
-    my $self = shift;
-    my @BUILD_calls;
-    foreach my $method (reverse $self->associated_metaclass->find_all_methods_by_name('BUILD')) {
-        push @BUILD_calls => '$instance->' . $method->{class} . '::BUILD($params)';
-    }
-    return join ";\n" => @BUILD_calls;
-}
-
-sub _generate_triggers {
-    my $self = shift;
-    my @trigger_calls;
-    foreach my $i ( 0 .. $#{ $self->_attributes } ) {
-        my $attr = $self->_attributes->[$i];
-
-        next unless $attr->can('has_trigger') && $attr->has_trigger;
-
-        my $init_arg = $attr->init_arg;
-
-        next unless defined $init_arg;
-
-        push @trigger_calls => '(exists $params->{\''
-            . $init_arg
-            . '\'}) && do {'
-            . "\n    "
-            . '$attrs->['
-            . $i
-            . ']->trigger->('
-            . '$instance, '
-            . $attr->inline_get('$instance')
-            . ', '
-            . ');' . "\n}";
-    }
-
-    return join ";\n" => @trigger_calls;
-}
-
-sub _generate_slot_initializer {
-    my $self  = shift;
-    my $index = shift;
-
-    my $attr = $self->_attributes->[$index];
-
-    my @source = ('## ' . $attr->name);
-
-    my $is_moose = $attr->isa('Moose::Meta::Attribute'); # XXX FIXME
-
-    if ($is_moose && defined($attr->init_arg) && $attr->is_required && !$attr->has_default && !$attr->has_builder) {
-        push @source => ('(exists $params->{\'' . $attr->init_arg . '\'}) ' .
-                        '|| ' . $self->_inline_throw_error('"Attribute (' . quotemeta($attr->name) . ') is required"') .';');
-    }
-
-    if (($attr->has_default || $attr->has_builder) && !($is_moose && $attr->is_lazy)) {
-
-        if ( defined( my $init_arg = $attr->init_arg ) ) {
-            push @source => 'if (exists $params->{\'' . $init_arg . '\'}) {';
-            push @source => ('my $val = $params->{\'' . $init_arg . '\'};');
-            push @source => $self->_generate_type_constraint_and_coercion($attr, $index)
-                if $is_moose;
-            push @source => $self->_generate_slot_assignment($attr, '$val', $index);
-            push @source => "} else {";
-        }
-            my $default;
-            if ( $attr->has_default ) {
-                $default = $self->_generate_default_value($attr, $index);
-            }
-            else {
-               my $builder = $attr->builder;
-               $default = '$instance->' . $builder;
-            }
-
-            push @source => '{'; # wrap this to avoid my $val overwrite warnings
-            push @source => ('my $val = ' . $default . ';');
-            push @source => $self->_generate_type_constraint_and_coercion($attr, $index)
-                if $is_moose;
-            push @source => $self->_generate_slot_assignment($attr, '$val', $index);
-            push @source => '}'; # close - wrap this to avoid my $val overrite warnings
-
-        push @source => "}" if defined $attr->init_arg;
-    }
-    elsif ( defined( my $init_arg = $attr->init_arg ) ) {
-        push @source => '(exists $params->{\'' . $init_arg . '\'}) && do {';
-
-            push @source => ('my $val = $params->{\'' . $init_arg . '\'};');
-            if ($is_moose && $attr->has_type_constraint) {
-                if ($attr->should_coerce && $attr->type_constraint->has_coercion) {
-                    push @source => $self->_generate_type_coercion(
-                        $attr,
-                        '$type_constraints[' . $index . ']',
-                        '$val',
-                        '$val'
-                    );
-                }
-                push @source => $self->_generate_type_constraint_check(
-                    $attr,
-                    '$type_constraint_bodies[' . $index . ']',
-                    '$type_constraints[' . $index . ']',
-                    '$val'
-                );
-            }
-            push @source => $self->_generate_slot_assignment($attr, '$val', $index);
-
-        push @source => "}";
-    }
-
-    return join "\n" => @source;
-}
-
-sub _generate_slot_assignment {
-    my ($self, $attr, $value, $index) = @_;
-
-    my $source;
-
-    if ( $attr->has_initializer ) {
-        return
-              '$attrs->['
-            . $index
-            . ']->set_initial_value($instance, '
-            . $value . ');';
-    }
-    else {
-        return $attr->inline_set(
-            '$instance',
-            $value
-        ) . ';';
-    }
-
-    return $source;
-}
-
-sub _generate_type_constraint_and_coercion {
-    my ($self, $attr, $index) = @_;
-
-    return unless $attr->has_type_constraint;
-
-    my @source;
-    if ($attr->should_coerce && $attr->type_constraint->has_coercion) {
-        push @source => $self->_generate_type_coercion(
-            $attr,
-            '$type_constraints[' . $index . ']',
-            '$val',
-            '$val'
-        );
-    }
-    push @source => $self->_generate_type_constraint_check(
-        $attr,
-        ('$type_constraint_bodies[' . $index . ']'),
-        ('$type_constraints[' . $index . ']'),
-        '$val'
-    );
-    return @source;
-}
-
-sub _generate_type_coercion {
-    my ($self, $attr, $type_constraint_name, $value_name, $return_value_name) = @_;
-    return ($return_value_name . ' = ' . $type_constraint_name .  '->coerce(' . $value_name . ');');
-}
-
-sub _generate_type_constraint_check {
-    my ($self, $attr, $type_constraint_cv, $type_constraint_obj, $value_name) = @_;
-    return (
-        $self->_inline_throw_error('"Attribute (' # FIXME add 'dad'
-        . quotemeta( $attr->name )
-        . ') does not pass the type constraint because: " . '
-        . $type_constraint_obj . '->get_message(' . $value_name . ')')
-        . "\n\t unless " .  $type_constraint_cv . '->(' . $value_name . ');'
-    );
+    return {
+        '$meta'  => \$self,
+        '$attrs' => \$attrs,
+        '$defaults' => \$defaults,
+        '@type_constraints' => \@type_constraints,
+        '@type_constraint_bodies' => \@type_constraint_bodies,
+    };
 }
 
 1;
index 4cc8129..810fa70 100644 (file)
@@ -6,7 +6,7 @@ use warnings;
 
 use Devel::GlobalDestruction ();
 use Scalar::Util 'blessed', 'weaken';
-use Try::Tiny ();
+use Try::Tiny;
 
 our $VERSION   = '1.19';
 $VERSION = eval $VERSION;
@@ -78,47 +78,58 @@ sub _initialize_body {
     # requires some adaption on the part of
     # the author, after all, nothing is free)
 
-    my @DEMOLISH_methods = $self->associated_metaclass->find_all_methods_by_name('DEMOLISH');
-
-    my $source;
-    $source  = 'sub {' . "\n";
-    $source .= 'my $self = shift;' . "\n";
-    $source .= 'return $self->Moose::Object::DESTROY(@_)' . "\n";
-    $source .= '    if Scalar::Util::blessed($self) ne ';
-    $source .= "'" . $self->associated_metaclass->name . "'";
-    $source .= ';' . "\n";
-
-    if ( @DEMOLISH_methods ) {
-        $source .= 'local $?;' . "\n";
-
-        $source .= 'my $in_global_destruction = Devel::GlobalDestruction::in_global_destruction;' . "\n";
-
-        $source .= 'Try::Tiny::try {' . "\n";
-
-        $source .= '$self->' . $_->{class} . '::DEMOLISH($in_global_destruction);' . "\n"
-            for @DEMOLISH_methods;
-
-        $source .= '}';
-        $source .= q[ Try::Tiny::catch { no warnings 'misc'; die $_ };] . "\n";
-        $source .= 'return;' . "\n";
+    my $class = $self->associated_metaclass->name;
+    my @source = (
+        'sub {',
+            'my $self = shift;',
+            'return ' . $self->_generate_fallback_destructor('$self'),
+                'if Scalar::Util::blessed($self) ne \'' . $class . '\';',
+            $self->_generate_DEMOLISHALL('$self'),
+        '}',
+    );
+    warn join("\n", @source) if $self->options->{debug};
 
+    my $code = try {
+        $self->_compile_code(source => \@source);
     }
+    catch {
+        my $source = join("\n", @source);
+        $self->throw_error(
+            "Could not eval the destructor :\n\n$source\n\nbecause :\n\n$_",
+            error => $_,
+            data  => $source,
+        );
+    };
 
-    $source .= '}';
-
-    warn $source if $self->options->{debug};
+    $self->{'body'} = $code;
+}
 
-    my ( $code, $e ) = $self->_compile_code(
-        environment => {},
-        code => $source,
-    );
+sub _generate_fallback_destructor {
+    my $self = shift;
+    my ($inv) = @_;
 
-    $self->throw_error(
-        "Could not eval the destructor :\n\n$source\n\nbecause :\n\n$e",
-        error => $e, data => $source )
-        if $e;
+    return $inv . '->Moose::Object::DESTROY(@_)';
+}
 
-    $self->{'body'} = $code;
+sub _generate_DEMOLISHALL {
+    my $self = shift;
+    my ($inv) = @_;
+
+    my @methods = $self->associated_metaclass->find_all_methods_by_name('DEMOLISH');
+    return unless @methods;
+
+    return (
+        'local $?;',
+        'my $igd = Devel::GlobalDestruction::in_global_destruction;',
+        'Try::Tiny::try {',
+            (map { $inv . '->' . $_->{class} . '::DEMOLISH($igd);' } @methods),
+        '}',
+        'Try::Tiny::catch {',
+            'no warnings \'misc\';',
+            'die $_;',
+        '};',
+        'return;',
+    );
 }
 
 
index 4803d3f..ada0a20 100644 (file)
@@ -157,6 +157,12 @@ $META->add_attribute(
     default => 'Moose::Meta::Role::Application::ToInstance',
 );
 
+$META->add_attribute(
+    'applied_attribute_metaclass',
+    reader  => 'applied_attribute_metaclass',
+    default => 'Moose::Meta::Attribute',
+);
+
 # More or less copied from Moose::Meta::Class
 sub initialize {
     my $class = shift;
@@ -196,6 +202,7 @@ sub reinitialize {
             application_to_class_class
             application_to_role_class
             application_to_instance_class
+            applied_attribute_metaclass
         );
     }
 
@@ -375,13 +382,6 @@ sub get_method_modifier_list {
     keys %{$self->$accessor};
 }
 
-sub reset_package_cache_flag  { (shift)->{'_package_cache_flag'} = undef }
-sub update_package_cache_flag {
-    my $self = shift;
-    $self->{'_package_cache_flag'} = Class::MOP::check_package_cache_flag($self->name);
-}
-
-
 sub _meta_method_class { 'Moose::Meta::Method::Meta' }
 
 ## ------------------------------------------------------------------
index 8954cd0..a7489ba 100644 (file)
@@ -129,7 +129,7 @@ sub check_required_attributes {
 
 sub apply_attributes {
     my ($self, $role, $class) = @_;
-    my $attr_metaclass = $class->attribute_metaclass;
+    my $attr_metaclass = $role->applied_attribute_metaclass;
 
     foreach my $attribute_name ($role->get_attribute_list) {
         # it if it has one already
index 364fb49..521367c 100644 (file)
@@ -1279,11 +1279,17 @@ See the L</SYNOPSIS> for an example of how to use these.
 
 =over 4
 
-=item B<< coerce 'Name' => from 'OtherName' => via { ... } >>
+=item B<< coerce 'Name' => from 'OtherName' => via { ... }  >>
 
 This defines a coercion from one type to another. The C<Name> argument
 is the type you are coercing I<to>.
 
+To define multiple coercions, supply more sets of from/via pairs:
+
+  coerce 'Name' =>
+    from 'OtherName' => via { ... },
+    from 'ThirdName' => via { ... };
+
 =item B<from 'OtherName'>
 
 This is just sugar for the type coercion construction syntax.
index e15a5e5..be8e242 100644 (file)
@@ -61,8 +61,8 @@ is($foo->lazy_classname, 'Parent', "lazy attribute initialized");
 is( exception { $foo->type_constrained(10.5) }, undef, "Num type constraint for now.." );
 
 # try to rebless, except it will fail due to Child's stricter type constraint
-like( exception { Child->meta->rebless_instance($foo) }, qr/^Attribute \(type_constrained\) does not pass the type constraint because\: Validation failed for 'Int' with value 10\.5/, '... this failed cause of type check' );
-like( exception { Child->meta->rebless_instance($bar) }, qr/^Attribute \(type_constrained\) does not pass the type constraint because\: Validation failed for 'Int' with value 5\.5/, '... this failed cause of type check' );
+like( exception { Child->meta->rebless_instance($foo) }, qr/^Attribute \(type_constrained\) does not pass the type constraint because\: Validation failed for 'Int' with value 10\.5/, '... this failed because of type check' );
+like( exception { Child->meta->rebless_instance($bar) }, qr/^Attribute \(type_constrained\) does not pass the type constraint because\: Validation failed for 'Int' with value 5\.5/, '... this failed because of type check' );
 
 $foo->type_constrained(10);
 $bar->type_constrained(5);
@@ -76,6 +76,6 @@ is($foo->name, 'Junior', "Child->name's default came through");
 is($foo->lazy_classname, 'Parent', "lazy attribute was already initialized");
 is($bar->lazy_classname, 'Child', "lazy attribute just now initialized");
 
-like( exception { $foo->type_constrained(10.5) }, qr/^Attribute \(type_constrained\) does not pass the type constraint because\: Validation failed for 'Int' with value 10\.5/, '... this failed cause of type check' );
+like( exception { $foo->type_constrained(10.5) }, qr/^Attribute \(type_constrained\) does not pass the type constraint because\: Validation failed for 'Int' with value 10\.5/, '... this failed because of type check' );
 
 done_testing;
diff --git a/t/030_roles/046_role_attr_application.t b/t/030_roles/046_role_attr_application.t
new file mode 100644 (file)
index 0000000..17b608a
--- /dev/null
@@ -0,0 +1,204 @@
+#!/usr/bin/env perl
+use strict;
+use warnings;
+use Test::More;
+
+{
+    package Foo::Meta::Attribute;
+    use Moose::Role;
+}
+
+{
+    package Foo::Meta::Attribute2;
+    use Moose::Role;
+}
+
+{
+    package Foo::Role;
+    use Moose::Role;
+
+    has foo => (is => 'ro');
+}
+
+{
+    package Foo;
+    use Moose;
+    Moose::Util::MetaRole::apply_metaroles(
+        for => __PACKAGE__,
+        class_metaroles => { attribute => ['Foo::Meta::Attribute'] },
+        role_metaroles  => { applied_attribute => ['Foo::Meta::Attribute2'] },
+    );
+    with 'Foo::Role';
+
+    has bar => (is => 'ro');
+}
+
+ok(Moose::Util::does_role(Foo->meta->get_attribute('bar'), 'Foo::Meta::Attribute'), "attrs defined in the class get the class metarole applied");
+ok(!Moose::Util::does_role(Foo->meta->get_attribute('bar'), 'Foo::Meta::Attribute2'), "attrs defined in the class don't get the role metarole applied");
+ok(!Moose::Util::does_role(Foo->meta->get_attribute('foo'), 'Foo::Meta::Attribute'), "attrs defined in the role don't get the metarole applied");
+ok(!Moose::Util::does_role(Foo->meta->get_attribute('foo'), 'Foo::Meta::Attribute'), "attrs defined in the role don't get the role metarole defined in the class applied");
+
+{
+    package Bar::Meta::Attribute;
+    use Moose::Role;
+}
+
+{
+    package Bar::Meta::Attribute2;
+    use Moose::Role;
+}
+
+{
+    package Bar::Role;
+    use Moose::Role;
+    Moose::Util::MetaRole::apply_metaroles(
+        for => __PACKAGE__,
+        class_metaroles => { attribute => ['Bar::Meta::Attribute'] },
+        role_metaroles  => { applied_attribute => ['Bar::Meta::Attribute2'] },
+    );
+
+    has foo => (is => 'ro');
+}
+
+{
+    package Bar;
+    use Moose;
+    with 'Bar::Role';
+
+    has bar => (is => 'ro');
+}
+
+ok(!Moose::Util::does_role(Bar->meta->get_attribute('bar'), 'Bar::Meta::Attribute'), "attrs defined in the class don't get the class metarole from the role applied");
+ok(!Moose::Util::does_role(Bar->meta->get_attribute('bar'), 'Bar::Meta::Attribute2'), "attrs defined in the class don't get the role metarole applied");
+ok(Moose::Util::does_role(Bar->meta->get_attribute('foo'), 'Bar::Meta::Attribute2'), "attrs defined in the role get the role metarole applied");
+ok(!Moose::Util::does_role(Bar->meta->get_attribute('foo'), 'Bar::Meta::Attribute'), "attrs defined in the role don't get the class metarole applied");
+
+{
+    package Baz::Meta::Attribute;
+    use Moose::Role;
+}
+
+{
+    package Baz::Meta::Attribute2;
+    use Moose::Role;
+}
+
+{
+    package Baz::Role;
+    use Moose::Role;
+    Moose::Util::MetaRole::apply_metaroles(
+        for => __PACKAGE__,
+        class_metaroles => { attribute => ['Baz::Meta::Attribute'] },
+        role_metaroles  => { applied_attribute => ['Baz::Meta::Attribute2'] },
+    );
+
+    has foo => (is => 'ro');
+}
+
+{
+    package Baz;
+    use Moose;
+    Moose::Util::MetaRole::apply_metaroles(
+        for => __PACKAGE__,
+        class_metaroles => { attribute => ['Baz::Meta::Attribute'] },
+        role_metaroles  => { applied_attribute => ['Baz::Meta::Attribute2'] },
+    );
+    with 'Baz::Role';
+
+    has bar => (is => 'ro');
+}
+
+ok(Moose::Util::does_role(Baz->meta->get_attribute('bar'), 'Baz::Meta::Attribute'), "attrs defined in the class get the class metarole applied");
+ok(!Moose::Util::does_role(Baz->meta->get_attribute('bar'), 'Baz::Meta::Attribute2'), "attrs defined in the class don't get the role metarole applied");
+ok(Moose::Util::does_role(Baz->meta->get_attribute('foo'), 'Baz::Meta::Attribute2'), "attrs defined in the role get the role metarole applied");
+ok(!Moose::Util::does_role(Baz->meta->get_attribute('foo'), 'Baz::Meta::Attribute'), "attrs defined in the role don't get the class metarole applied");
+
+{
+    package Accessor::Modifying::Role;
+    use Moose::Role;
+
+    around _process_options => sub {
+        my $orig = shift;
+        my $self = shift;
+        my ($name, $params) = @_;
+        $self->$orig(@_);
+        $params->{reader} .= '_foo';
+    };
+}
+
+{
+    package Plain::Role;
+    use Moose::Role;
+
+    has foo => (
+        is  => 'ro',
+        isa => 'Str',
+    );
+}
+
+{
+    package Class::With::Trait;
+    use Moose;
+    Moose::Util::MetaRole::apply_metaroles(
+        for => __PACKAGE__,
+        class_metaroles => {
+            attribute => ['Accessor::Modifying::Role'],
+        },
+    );
+    with 'Plain::Role';
+
+    has bar => (
+        is  => 'ro',
+        isa => 'Str',
+    );
+}
+
+{
+    can_ok('Class::With::Trait', 'foo');
+    can_ok('Class::With::Trait', 'bar_foo');
+}
+
+{
+    package Role::With::Trait;
+    use Moose::Role;
+    Moose::Util::MetaRole::apply_metaroles(
+        for => __PACKAGE__,
+        role_metaroles => {
+            applied_attribute => ['Accessor::Modifying::Role'],
+        },
+    );
+    with 'Plain::Role';
+
+    has foo => (
+        is  => 'ro',
+        isa => 'Str',
+    );
+
+    sub foo_test {
+        my $self = shift;
+        return $self->can('foo_foo');
+    }
+}
+
+{
+    package Class::With::Role::With::Trait;
+    use Moose;
+    with 'Role::With::Trait';
+
+    has bar => (
+        is  => 'ro',
+        isa => 'Str',
+    );
+
+    sub bar_test {
+        my $self = shift;
+        return $self->can('bar');
+    }
+}
+
+{
+    can_ok('Class::With::Role::With::Trait', 'foo_foo');
+    can_ok('Class::With::Role::With::Trait', 'bar');
+}
+
+done_testing;
index f56fc59..a16bee7 100644 (file)
@@ -7,13 +7,16 @@ use Test::Fatal;
 
 our $called = 0;
 {
-    package Foo::Trait::Constructor;
+    package Foo::Trait::Class;
     use Moose::Role;
 
-    around _generate_BUILDALL => sub {
+    around _inline_BUILDALL => sub {
         my $orig = shift;
         my $self = shift;
-        return $self->$orig(@_) . '$::called++;';
+        return (
+            $self->$orig(@_),
+            '$::called++;'
+        );
     }
 }
 
@@ -23,7 +26,7 @@ our $called = 0;
     Moose::Util::MetaRole::apply_metaroles(
         for => __PACKAGE__,
         class_metaroles => {
-            constructor => ['Foo::Trait::Constructor'],
+            class => ['Foo::Trait::Class'],
         }
     );
 }
@@ -35,8 +38,8 @@ Foo->meta->make_immutable;
 Foo->new;
 is($called, 1, "inlined constructor has trait modifications");
 
-ok(Foo->meta->constructor_class->meta->does_role('Foo::Trait::Constructor'),
-   "class has correct constructor traits");
+ok(Foo->meta->meta->does_role('Foo::Trait::Class'),
+   "class has correct traits");
 
 {
     package Foo::Sub;
@@ -52,11 +55,11 @@ is($called, 0, "no calls before inlining");
 Foo::Sub->meta->make_immutable;
 
 Foo::Sub->new;
-is($called, 1, "inherits constructor trait properly");
+is($called, 1, "inherits trait properly");
 
-ok(Foo::Sub->meta->constructor_class->meta->can('does_role')
-&& Foo::Sub->meta->constructor_class->meta->does_role('Foo::Trait::Constructor'),
-   "subclass inherits constructor traits");
+ok(Foo::Sub->meta->meta->can('does_role')
+&& Foo::Sub->meta->meta->does_role('Foo::Trait::Class'),
+   "subclass inherits traits");
 
 {
     package Foo2::Role;