Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Any::Moose instead of Moose #1

Closed
wants to merge 1 commit into from

3 participants

@wchristian

And here's the partner pull request for the Email::Sender one. :)

@rjbs
Owner

I'm sorry to say that I can't just accept this. I already did all this work myself at YAPC::Asia and just haven't posted about it yet.

Throwable is meant to be a role that anyone can consume liberally and safely, and using Any::Moose totally undercuts that.

Say you write a library called Foo. It uses Any::Moose for a bunch of stuff, but then you want to use Email::Sender. This will load Moose, and now your Any::Moose work was all for nothing. It's natural, then, that you want Email::Sender to use Any::Moose, and right now, as you noted, that means Throwable needs to not strictly use Moose. Imagine that we have done this, though -- Throwable uses Any::Moose, so when you use Foo you get a Mouse-powered Throwable.

Everything works! Great!

Unfortunately, you also sometimes use another library called Bar. In Bar, there are custom exceptions, and those exceptions have long been Throwable-based. Bar::Error is a Moose class that composes Throwable as well as some MooseX extensions.

Now if you load Bar, Moose is loaded first, Throwable becomes a Moose role (because Any::Moose sees that Moose is loaded) and everything works nicely.

If you load Foo first, though, Any::Moose will find nothing yet loaded, and will use Mouse. Throwable becomes a Mouse role. Then, when Bar::Error is initialized, it throws an error when it tries to apply Throwable (now a Mouse role) to a Moose class.

The ability to interoperate becomes load-order-based. This is totally unacceptable for something intended to be used freely and widely, like Throwable.

The solution is probably to have Any::Throwable, which can be used only when the rest of the set of classes into which it is composed are all using Any::Moose.

@wchristian

Ah dang it, not so easy then. Thanks for the explanation though, makes perfect sense! :)

@wchristian wchristian closed this
@dolmen

For the posterity, I'm adding a link to RJBS's blog post on the subject.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 21, 2011
  1. @wchristian

    Any::Moose instead of Moose

    wchristian authored
This page is out of date. Refresh to see the latest.
View
13 lib/StackTrace/Auto.pm
@@ -1,5 +1,5 @@
package StackTrace::Auto;
-use Moose::Role 0.87;
+use Any::Moose 'Role';
# ABSTRACT: a role for generating stack traces during instantiation
=head1 SYNOPSIS
@@ -7,7 +7,7 @@ use Moose::Role 0.87;
First, include StackTrace::Auto in a Moose class...
package Some::Class;
- use Moose;
+ use Any::Moose;
with 'StackTrace::Auto';
...then create an object of that class...
@@ -34,7 +34,7 @@ In general, you will not need to think about this attribute.
=cut
{
- use Moose::Util::TypeConstraints;
+ use Any::Moose 'Util::TypeConstraints';
has stack_trace => (
is => 'ro',
@@ -43,8 +43,9 @@ In general, you will not need to think about this attribute.
init_arg => undef,
);
+ require Class::Load;
my $tc = subtype as 'ClassName';
- coerce $tc, from 'Str', via { Class::MOP::load_class($_); $_ };
+ coerce $tc, from 'Str', via { Class::Load::load_class($_); $_ };
has stack_trace_class => (
is => 'ro',
@@ -54,7 +55,7 @@ In general, you will not need to think about this attribute.
builder => '_build_stack_trace_class',
);
- no Moose::Util::TypeConstraints;
+ no Any::Moose 'Util::TypeConstraints';
}
=attr stack_trace_args
@@ -113,5 +114,5 @@ sub __stack_marker {
return $self->$next(@_);
}
-no Moose::Role;
+no Any::Moose 'Role';
1;
View
6 lib/Throwable.pm
@@ -1,11 +1,11 @@
package Throwable;
-use Moose::Role 0.87;
+use Any::Moose 'Role';
# ABSTRACT: a role for classes that can be thrown
=head1 SYNOPSIS
package Redirect;
- use Moose;
+ use Any::Moose;
with 'Throwable';
has url => (is => 'ro');
@@ -59,5 +59,5 @@ sub throw {
die $throwable;
}
-no Moose::Role;
+no Any::Moose 'Role';
1;
View
6 lib/Throwable/Error.pm
@@ -1,12 +1,12 @@
package Throwable::Error;
-use Moose 0.87;
+use Any::Moose;
with 'Throwable', 'StackTrace::Auto';
# ABSTRACT: an easy-to-use class for error objects
=head1 SYNOPSIS
package MyApp::Error;
- use Moose;
+ use Any::Moose;
extends 'Throwable::Error';
has execution_phase => (
@@ -95,5 +95,5 @@ sub BUILDARGS {
}
__PACKAGE__->meta->make_immutable(inline_constructor => 0);
-no Moose;
+no Any::Moose;
1;
View
4 t/basic.t
@@ -5,9 +5,9 @@ use Test::More tests => 9;
{
package MyError;
- use Moose;
+ use Any::Moose;
extends 'Throwable::Error';
- no Moose;
+ no Any::Moose;
}
sub throw_x {
Something went wrong with that request. Please try again.