Subject: | [PATCH] Document namespace cleaning in Moo |
Hello,
I've attached a doc patch that explains how to make sure your imports are properly cleaned from a Moo-using package. Please let me know if you'd like me to make any improvements to it.
Cheers,
Fitz
Subject: | 0001-add-pod-how-to-clean-imported-functions.patch |
From 094cf09d67edccd444d4b3201b5f1e6908437178 Mon Sep 17 00:00:00 2001
From: Fitz Elliott <fitz.elliott@gmail.com>
Date: Thu, 26 Sep 2013 16:47:18 -0400
Subject: [PATCH] add pod: how to clean imported functions
diff --git a/lib/Moo.pm b/lib/Moo.pm
index 0dfaf8d..1702dc5 100644
--- a/lib/Moo.pm
+++ b/lib/Moo.pm
@@ -206,6 +206,7 @@ Moo - Minimalist Object Orientation (with Moose compatibility)
package Cat::Food;
use Moo;
+ use namespace::clean;
sub feed_lion {
my $self = shift;
@@ -703,9 +704,11 @@ aware can take advantage of this.
To do this, you can write
- use Moo;
use Sub::Quote;
+ use Moo;
+ use namespace::clean;
+
has foo => (
is => 'ro',
isa => quote_sub(q{ die "Not <3" unless $_[0] < 3 })
@@ -735,6 +738,47 @@ which will be inlined as
See L<Sub::Quote> for more information, including how to pass lexical
captures that will also be compiled into the subroutine.
+=head1 CLEANING UP IMPORTS
+
+L<Moo> will not clean up imported subroutines for you; you will have
+to do that manually. The recommended way to do this is to declare your
+imports first, then C<use Moo>, then C<use namespace::clean>.
+Anything imported before L<namespace::clean> will be scrubbed.
+Anything imported or declared after will be still be available.
+
+ package Record;
+
+ use Digest::MD5 qw(md5_hex);
+
+ use Moo;
+ use namespace::clean;
+
+ has name => (is => 'ro', required => 1);
+ has id => (is => 'lazy');
+ sub _build_id {
+ my ($self) = @_;
+ return md5_hex($self->name);
+ }
+
+ 1;
+
+If you were to import C<md5_hex> after L<namespace::clean> you would
+be able to call C<< ->md5_hex() >> on your C<Record> instances (and it
+probably wouldn't do what you expect!).
+
+L<Moo:Role>s behave slightly differently. Since their methods are
+composed into the consuming class, they can do a little more for you
+automatically. As long as you declare your imports before calling
+C<use Moo::Role>, those imports and the ones L<Moo::Role> itself
+provides will be scrubbed for you. There's no need to use
+L<namespace::clean>.
+
+B<On L<namespace::autoclean>:> If you're coming to Moo from the Moose
+world, you may be accustomed to using L<namespace::autoclean> in all
+your packages. This is not recommended for L<Moo> packages, because
+L<namespace::autoclean> will inflate your class to a full L<Moose>
+class. It'll work, but you will lose the benefits of L<Moo>.
+
=head1 INCOMPATIBILITIES WITH MOOSE
There is no built-in type system. C<isa> is verified with a coderef; if you
diff --git a/lib/Moo/Role.pm b/lib/Moo/Role.pm
index 71db848..1bf00fa 100644
--- a/lib/Moo/Role.pm
+++ b/lib/Moo/Role.pm
@@ -398,6 +398,33 @@ imported by this module.
Declares an attribute for the class to be composed into. See
L<Moo/has> for all options.
+=head1 CLEANING UP IMPORTS
+
+L<Moo::Role> cleans up its own imported methods and any imports
+declared before the C<use Moo::Role> statement automatically.
+Anything imported after C<use Moo::Role> will be composed into
+consuming packages. A package that consumes this role:
+
+ package My::Role::ID;
+
+ use Digest::MD5 qw(md5_hex);
+ use Moo::Role;
+ use Digest::SHA qw(sha1_hex);
+
+ requires 'name';
+
+ sub as_md5 { my ($self) = @_; return md5_hex($self->name); }
+ sub as_sha1 { my ($self) = @_; return sha1_hex($self->name); }
+
+ 1;
+
+..will now have a C<< $self->sha1_hex() >> method available to it
+that probably does not do what you expect. On the other hand, a call
+to C<< $self->md5_hex() >> will die with the helpful error message:
+C<Can't locate object method "md5_hex">.
+
+See L<Moo/"CLEANING UP IMPORTS"> for more details.
+
=head1 SUPPORT
See L<Moo> for support and contact information.
--
1.8.4