-
package Moose;
-
use strict;
use warnings;
use 5.008;
-our $VERSION = '0.58';
+our $VERSION = '0.92';
$VERSION = eval $VERSION;
our $AUTHORITY = 'cpan:STEVAN';
use Scalar::Util 'blessed';
-use Carp 'confess', 'croak', 'cluck';
+use Carp 'confess';
use Moose::Exporter;
-use Class::MOP 0.65;
+use Class::MOP 0.94;
use Moose::Meta::Class;
use Moose::Meta::TypeConstraint;
use Moose::Util::TypeConstraints;
use Moose::Util ();
+use Moose::Meta::Attribute::Native;
+
sub throw_error {
- # FIXME This
+ # FIXME This
shift;
goto \&confess
}
sub extends {
- my $class = shift;
-
- croak "Must derive at least one class" unless @_;
-
- my @supers = @_;
- foreach my $super (@supers) {
- Class::MOP::load_class($super);
- croak "You cannot inherit from a Moose Role ($super)"
- if $super->can('meta') &&
- blessed $super->meta &&
- $super->meta->isa('Moose::Meta::Role')
- }
-
+ my $meta = shift;
+ Moose->throw_error("Must derive at least one class") unless @_;
# this checks the metaclass to make sure
# it is correct, sometimes it can get out
# of sync when the classes are being built
- my $meta = Moose::Meta::Class->initialize($class);
- $meta->superclasses(@supers);
+ $meta->superclasses(@_);
}
sub with {
- my $class = shift;
- Moose::Util::apply_all_roles(Class::MOP::Class->initialize($class), @_);
+ Moose::Util::apply_all_roles(shift, @_);
}
sub has {
- my $class = shift;
- my $name = shift;
- croak 'Usage: has \'name\' => ( key => value, ... )' if @_ == 1;
- my %options = @_;
+ my $meta = shift;
+ my $name = shift;
+
+ Moose->throw_error('Usage: has \'name\' => ( key => value, ... )')
+ if @_ % 2 == 1;
+
+ my %options = ( definition_context => Moose::Util::_caller_info(), @_ );
my $attrs = ( ref($name) eq 'ARRAY' ) ? $name : [ ($name) ];
- Class::MOP::Class->initialize($class)->add_attribute( $_, %options ) for @$attrs;
+ $meta->add_attribute( $_, %options ) for @$attrs;
}
sub before {
- my $class = shift;
- Moose::Util::add_method_modifier($class, 'before', \@_);
+ Moose::Util::add_method_modifier(shift, 'before', \@_);
}
sub after {
- my $class = shift;
- Moose::Util::add_method_modifier($class, 'after', \@_);
+ Moose::Util::add_method_modifier(shift, 'after', \@_);
}
sub around {
- my $class = shift;
- Moose::Util::add_method_modifier($class, 'around', \@_);
+ Moose::Util::add_method_modifier(shift, 'around', \@_);
}
+our $SUPER_PACKAGE;
+our $SUPER_BODY;
+our @SUPER_ARGS;
+
sub super {
- return unless our $SUPER_BODY; $SUPER_BODY->(our @SUPER_ARGS);
+ # This check avoids a recursion loop - see
+ # t/100_bugs/020_super_recursion.t
+ return if defined $SUPER_PACKAGE && $SUPER_PACKAGE ne caller();
+ return unless $SUPER_BODY; $SUPER_BODY->(@SUPER_ARGS);
}
sub override {
- my $class = shift;
+ my $meta = shift;
my ( $name, $method ) = @_;
- Class::MOP::Class->initialize($class)->add_override_method_modifier( $name => $method );
+ $meta->add_override_method_modifier( $name => $method );
}
sub inner {
}
sub augment {
- my $class = shift;
+ my $meta = shift;
my ( $name, $method ) = @_;
- Class::MOP::Class->initialize($class)->add_augment_method_modifier( $name => $method );
-}
-
-sub make_immutable {
- my $class = shift;
- cluck "The make_immutable keyword has been deprecated, " .
- "please go back to __PACKAGE__->meta->make_immutable\n";
- Class::MOP::Class->initialize($class)->make_immutable(@_);
+ $meta->add_augment_method_modifier( $name => $method );
}
Moose::Exporter->setup_import_methods(
- with_caller => [
- qw( extends with has before after around override augment make_immutable )
+ with_meta => [
+ qw( extends with has before after around override augment )
],
as_is => [
qw( super inner ),
my $ancestor_meta = Class::MOP::get_metaclass_by_name($ancestor) || next;
my $ancestor_meta_class = ($ancestor_meta->is_immutable
- ? $ancestor_meta->get_mutable_metaclass_name
+ ? $ancestor_meta->_get_mutable_metaclass_name
: ref($ancestor_meta));
# if we have an ancestor metaclass that inherits $metaclass, we use
my $method_meta = $class->meta;
( blessed($method_meta) && $method_meta->isa('Moose::Meta::Class') )
- || Moose->throw_error("$class already has a &meta function, but it does not return a Moose::Meta::Class ($meta)");
+ || Moose->throw_error("$class already has a &meta function, but it does not return a Moose::Meta::Class ($method_meta)");
$meta = $method_meta;
}
## make 'em all immutable
-$_->meta->make_immutable(
+$_->make_immutable(
inline_constructor => 1,
constructor_name => "_new",
- inline_accessors => 1, # these are Class::MOP accessors, so they need inlining
- )
- for (qw(
+ # these are Class::MOP accessors, so they need inlining
+ inline_accessors => 1
+ ) for grep { $_->is_mutable }
+ map { $_->meta }
+ qw(
Moose::Meta::Attribute
Moose::Meta::Class
Moose::Meta::Instance
- Moose::Meta::TypeConstraint
- Moose::Meta::TypeConstraint::Union
- Moose::Meta::TypeConstraint::Parameterized
- Moose::Meta::TypeConstraint::Parameterizable
- Moose::Meta::TypeConstraint::Enum
- Moose::Meta::TypeConstraint::Class
- Moose::Meta::TypeConstraint::Role
- Moose::Meta::TypeConstraint::Registry
Moose::Meta::TypeCoercion
Moose::Meta::TypeCoercion::Union
Moose::Meta::Method::Accessor
Moose::Meta::Method::Constructor
Moose::Meta::Method::Destructor
- Moose::Meta::Method::Overriden
+ Moose::Meta::Method::Overridden
Moose::Meta::Method::Augmented
Moose::Meta::Role
Moose::Meta::Role::Method
Moose::Meta::Role::Method::Required
+ Moose::Meta::Role::Method::Conflicting
Moose::Meta::Role::Composite
Moose::Meta::Role::Application::ToClass
Moose::Meta::Role::Application::ToRole
Moose::Meta::Role::Application::ToInstance
-));
+);
1;
=head2 New to Moose?
-If you're new to Moose, the best place to start is the L<Moose::Intro>
-docs, followed by the L<Moose::Cookbook>. The intro will show you what
-Moose is, and how it makes Perl 5 OO better.
+If you're new to Moose, the best place to start is the
+L<Moose::Manual> docs, followed by the L<Moose::Cookbook>. The intro
+will show you what Moose is, and how it makes Perl 5 OO better.
The cookbook recipes on Moose basics will get you up to speed with
many of Moose's features quickly. Once you have an idea of what Moose
or to examine L<Task::Moose> which aims to keep an up-to-date, easily
installable list of Moose extensions.
+=head1 TRANSLATIONS
+
+Much of the Moose documentation has been translated into other languages.
+
+=over 4
+
+=item L<http://github.com/jpa/Moose-Doc-JA>
+
+=back
+
=head1 BUILDING CLASSES WITH MOOSE
Moose makes every attempt to provide as much convenience as possible during
=head1 PROVIDED METHODS
-Moose provides a number of methods to all your classes, mostly through the
+Moose provides a number of methods to all your classes, mostly through the
inheritance of L<Moose::Object>. There is however, one exception.
=over 4
=item B<with (@roles)>
-This will apply a given set of C<@roles> to the local class.
+This will apply a given set of C<@roles> to the local class.
-=item B<has $name =E<gt> %options>
+=item B<has $name|@$names =E<gt> %options>
-This will install an attribute of a given C<$name> into the current class.
-The C<%options> are the same as those provided by
-L<Class::MOP::Attribute>, in addition to the list below which are provided
-by Moose (L<Moose::Meta::Attribute> to be more specific):
+This will install an attribute of a given C<$name> into the current class. If
+the first parameter is an array reference, it will create an attribute for
+every C<$name> in the list. The C<%options> are the same as those provided by
+L<Class::MOP::Attribute>, in addition to the list below which are provided by
+Moose (L<Moose::Meta::Attribute> to be more specific):
=over 4
only). These will create either a read/write accessor or a read-only
accessor respectively, using the same name as the C<$name> of the attribute.
-If you need more control over how your accessors are named, you can use the
-I<reader>, I<writer> and I<accessor> options inherited from
-L<Class::MOP::Attribute>, however if you use those, you won't need the I<is>
-option.
+If you need more control over how your accessors are named, you can
+use the L<reader|Class::MOP::Attribute/reader>,
+L<writer|Class::MOP::Attribute/writer> and
+L<accessor|Class::MOP::Attribute/accessor> options inherited from
+L<Class::MOP::Attribute>, however if you use those, you won't need the
+I<is> option.
=item I<isa =E<gt> $type_name>
=item I<required =E<gt> (1|0)>
-This marks the attribute as being required. This means a I<defined> value must be
-supplied during class construction, and the attribute may never be set to
-C<undef> with an accessor.
+This marks the attribute as being required. This means a value must be
+supplied during class construction, I<or> the attribute must be lazy
+and have either a default or a builder. Note that c<required> does not
+say anything about the attribute's value, which can be C<undef>.
=item I<weak_ref =E<gt> (1|0)>
=item I<trigger =E<gt> $code>
-The I<trigger> option is a CODE reference which will be called after the value of
-the attribute is set. The CODE ref will be passed the instance itself, the
-updated value and the attribute meta-object (this is for more advanced fiddling
-and can typically be ignored). You B<cannot> have a trigger on a read-only
-attribute.
+The I<trigger> option is a CODE reference which will be called after
+the value of the attribute is set. The CODE ref will be passed the
+instance itself and the updated value. If the attribute already had a
+value, this will be passed as the third value to the trigger.
+
+You B<can> have a trigger on a read-only attribute.
+
+B<NOTE:> Triggers will only fire when you B<assign> to the attribute,
+either in the constructor, or using the writer. Default and built values will
+B<not> cause the trigger to be fired.
-=item I<handles =E<gt> ARRAY | HASH | REGEXP | ROLE | CODE>
+=item I<handles =E<gt> ARRAY | HASH | REGEXP | ROLE | DUCKTYPE | CODE>
The I<handles> option provides Moose classes with automated delegation features.
This is a pretty complex and powerful option. It accepts many different option
overriding locally defined methods, if you do want to do this, you should do it
manually, not with Moose.
-You do not I<need> to have a reader (or accessor) for the attribute in order
-to delegate to it. Moose will create a means of accessing the value for you,
-however this will be several times B<less> efficient then if you had given
+You do not I<need> to have a reader (or accessor) for the attribute in order
+to delegate to it. Moose will create a means of accessing the value for you,
+however this will be several times B<less> efficient then if you had given
the attribute a reader (or accessor) to use.
Below is the documentation for each option format:
which delegate to the C<node> and C<children> methods (respectively) of the Tree
instance stored in the C<parent> slot.
+You may also use an array reference to curry arguments to the original method.
+
+ has 'thing' => (
+ ...
+ handles => { set_foo => [ set => 'foo' ] },
+ );
+
+ # $self->set_foo(...) calls $self->thing->set('foo', ...)
+
+The first element of the array reference is the original method name, and the
+rest is a list of curried arguments.
+
=item C<REGEXP>
The regexp option works very similar to the ARRAY option, except that it builds
that this does B<not> include any method modifiers or generated attribute
methods (which is consistent with role composition).
+=item C<DUCKTYPE>
+
+With the duck type option, you pass a duck type object whose "interface" then
+becomes the list of methods to handle. The "interface" can be defined as; the
+list of methods passed to C<duck_type> to create a duck type object. For more
+information on C<duck_type> please check
+L<Moose::Util::TypeConstraints>.
+
=item C<CODE>
This is the option to use when you really want to do something funky. You should
This tells the class to use a custom attribute metaclass for this particular
attribute. Custom attribute metaclasses are useful for extending the
capabilities of the I<has> keyword: they are the simplest way to extend the MOP,
-but they are still a fairly advanced topic and too much to cover here, see
+but they are still a fairly advanced topic and too much to cover here, see
L<Moose::Cookbook::Meta::Recipe1> for more information.
-The default behavior here is to just load C<$metaclass_name>; however, we also
-have a way to alias to a shorter name. This will first look to see if
-B<Moose::Meta::Attribute::Custom::$metaclass_name> exists. If it does, Moose
-will then check to see if that has the method C<register_implementation>, which
-should return the actual name of the custom attribute metaclass. If there is no
-C<register_implementation> method, it will fall back to using
-B<Moose::Meta::Attribute::Custom::$metaclass_name> as the metaclass name.
+See L<Metaclass and Trait Name Resolution> for details on how a metaclass name
+is resolved to a class name.
=item I<traits =E<gt> [ @role_names ]>
-This tells Moose to take the list of C<@role_names> and apply them to the
-attribute meta-object. This is very similar to the I<metaclass> option, but
+This tells Moose to take the list of C<@role_names> and apply them to the
+attribute meta-object. This is very similar to the I<metaclass> option, but
allows you to use more than one extension at a time.
-See L<TRAIT NAME RESOLUTION> for details on how a trait name is
-resolved to a class name.
+See L<Metaclass and Trait Name Resolution> for details on how a trait name is
+resolved to a role name.
Also see L<Moose::Cookbook::Meta::Recipe3> for a metaclass trait
example.
+=item I<builder> => Str
+
+The value of this key is the name of the method that will be called to
+obtain the value used to initialize the attribute. See the L<builder
+option docs in Class::MOP::Attribute|Class::MOP::Attribute/builder>
+ and/or L<Moose::Cookbook::Basics::Recipe8> for more information.
+
+=item I<default> => SCALAR | CODE
+
+The value of this key is the default value which will initialize the attribute.
+
+NOTE: If the value is a simple scalar (string or number), then it can
+be just passed as is. However, if you wish to initialize it with a
+HASH or ARRAY ref, then you need to wrap that inside a CODE reference.
+See the L<default option docs in
+Class::MOP::Attribute|Class::MOP::Attribute/default> for more
+information.
+
+=item I<clearer> => Str
+
+Creates a method allowing you to clear the value, see the L<clearer option
+docs in Class::MOP::Attribute|Class::MOP::Attribute/clearer> for more
+information.
+
+=item I<predicate> => Str
+
+Creates a method to perform a basic test to see if a value has been set in the
+attribute, see the L<predicate option docs in
+Class::MOP::Attribute|Class::MOP::Attribute/predicate> for more information.
+
+=item I<lazy_build> => (0|1)
+
+Automatically define lazy => 1 as well as builder => "_build_$attr", clearer =>
+"clear_$attr', predicate => 'has_$attr' unless they are already defined.
+
+=item I<initializer> => Str
+
+This may be a method name (referring to a method on the class with
+this attribute) or a CODE ref. The initializer is used to set the
+attribute value on an instance when the attribute is set during
+instance initialization (but not when the value is being assigned
+to). See the L<initializer option docs in
+Class::MOP::Attribute|Class::MOP::Attribute/initializer> for more
+information.
+
+=item I<documentation> => $string
+
+An arbitrary string that can be retrieved later by calling C<<
+$attr->documentation >>.
+
+
+
=back
=item B<has +$name =E<gt> %options>
-This is variation on the normal attibute creator C<has> which allows you to
-clone and extend an attribute from a superclass or from a role. Here is an
+This is variation on the normal attribute creator C<has> which allows you to
+clone and extend an attribute from a superclass or from a role. Here is an
example of the superclass usage:
package Foo;
has '+message' => (default => 'Hello I am My::Foo');
-In this case, we are basically taking the attribute which the role supplied
-and altering it within the bounds of this feature.
+In this case, we are basically taking the attribute which the role supplied
+and altering it within the bounds of this feature.
+
+Note that you can only extend an attribute from either a superclass or a role,
+you cannot extend an attribute in a role that composes over an attribute from
+another role.
-Aside from where the attributes come from (one from superclass, the other
-from a role), this feature works exactly the same. This feature is restricted
-somewhat, so as to try and force at least I<some> sanity into it. You are only
+Aside from where the attributes come from (one from superclass, the other
+from a role), this feature works exactly the same. This feature is restricted
+somewhat, so as to try and force at least I<some> sanity into it. You are only
allowed to change the following attributes:
=over 4
=item I<isa>
-You I<are> allowed to change the type without restriction.
+You I<are> allowed to change the type without restriction.
-It is recommended that you use this freedom with caution. We used to
-only allow for extension only if the type was a subtype of the parent's
-type, but we felt that was too restrictive and is better left as a
-policy descision.
+It is recommended that you use this freedom with caution. We used to
+only allow for extension only if the type was a subtype of the parent's
+type, but we felt that was too restrictive and is better left as a
+policy decision.
=item I<handles>
=item I<traits>
You are allowed to B<add> additional traits to the C<traits> definition.
-These traits will be composed into the attribute, but pre-existing traits
+These traits will be composed into the attribute, but preexisting traits
B<are not> overridden, or removed.
=back
=item B<around $name|@names =E<gt> sub { ... }>
-This three items are syntactic sugar for the before, after, and around method
+These three items are syntactic sugar for the before, after, and around method
modifier features that L<Class::MOP> provides. More information on these may be
-found in the L<Class::MOP::Class documentation|Class::MOP::Class/"Method
-Modifiers"> for now.
+found in L<Moose::Manual::MethodModifiers> and the
+L<Class::MOP::Class documentation|Class::MOP::Class/"Method Modifiers">.
=item B<super>
=item B<confess>
This is the C<Carp::confess> function, and exported here because I use it
-all the time.
+all the time.
=item B<blessed>
=back
-=head1 METACLASS TRAITS
+=head1 METACLASS
+
+When you use Moose, you can specify which metaclass to use:
-When you use Moose, you can also specify traits which will be applied
-to your metaclass:
+ use Moose -metaclass => 'My::Meta::Class';
+
+You can also specify traits which will be applied to your metaclass:
use Moose -traits => 'My::Trait';
This is very similar to the attribute traits feature. When you do
this, your class's C<meta> object will have the specified traits
-applied to it. See L<TRAIT NAME RESOLUTION> for more details.
+applied to it. See L<Metaclass and Trait Name Resolution> for more
+details.
-=head1 TRAIT NAME RESOLUTION
+=head2 Metaclass and Trait Name Resolution
By default, when given a trait name, Moose simply tries to load a
class of the same name. If such a class does not exist, it then looks
C<register_implementation> method, it will fall back to using
B<Moose::Meta::$type::Custom::Trait::$trait> as the trait name.
+The lookup method for metaclasses is the same, except that it looks
+for a class matching B<Moose::Meta::$type::Custom::$metaclass_name>.
+
If all this is confusing, take a look at
L<Moose::Cookbook::Meta::Recipe3>, which demonstrates how to create an
attribute trait.
into the class so you can get at this object. It also sets the class's
superclass to C<base_class>, with L<Moose::Object> as the default.
-You can specify an alternate metaclass with the C<metaclass> parameter.
+C<init_meta> returns the metaclass object for C<$class>.
+
+You can specify an alternate metaclass with the C<metaclass> option.
For more detail on this topic, see L<Moose::Cookbook::Extending::Recipe2>.
Ultimately, this is all transparent to you except in the case of an
unresolvable conflict.
+=head2 The MooseX:: namespace
+
+Generally if you're writing an extension I<for> Moose itself you'll want
+to put your extension in the C<MooseX::> namespace. This namespace is
+specifically for extensions that make Moose better or different in some
+fundamental way. It is traditionally B<not> for a package that just happens
+to use Moose. This namespace follows from the examples of the C<LWPx::>
+and C<DBIx::> namespaces that perform the same function for C<LWP> and C<DBI>
+respectively.
+
=head1 CAVEATS
=over 4
=back
+=head1 GETTING HELP
+
+We offer both a mailing list and a very active IRC channel.
+
+The mailing list is L<moose@perl.org>. You must be subscribed to send
+a message. To subscribe, send an empty message to
+L<moose-subscribe@perl.org>
+
+You can also visit us at L<#moose on
+irc.perl.org|irc://irc.perl.org/#moose>. This channel is quite active,
+and questions at all levels (on Moose-related topics ;) are welcome.
+
=head1 ACKNOWLEDGEMENTS
=over 4
=item L<http://www.iinteractive.com/moose>
-This is the official web home of Moose, it contains links to our public SVN repo
+This is the official web home of Moose, it contains links to our public SVN repository
as well as links to a number of talks and articles on Moose and Moose related
technologies.
-=item L<Moose::Cookbook> - How to cook a Moose
-
=item The Moose is flying, a tutorial by Randal Schwartz
Part 1 - L<http://www.stonehenge.com/merlyn/LinuxMag/col94.html>
Part 2 - L<http://www.stonehenge.com/merlyn/LinuxMag/col95.html>
-=item L<Class::MOP> documentation
-
-=item The #moose channel on irc.perl.org
-
-=item The Moose mailing list - moose@perl.org
-
-=item Moose stats on ohloh.net - L<http://www.ohloh.net/projects/moose>
-
=item Several Moose extension modules in the C<MooseX::> namespace.
See L<http://search.cpan.org/search?query=MooseX::> for extensions.
+=item Moose stats on ohloh.net - L<http://www.ohloh.net/projects/moose>
+
=back
=head2 Books
=item The Art of the MetaObject Protocol
-I mention this in the L<Class::MOP> docs too, this book was critical in
+I mention this in the L<Class::MOP> docs too, this book was critical in
the development of both modules and is highly recommended.
=back
=head1 BUGS
All complex software has bugs lurking in it, and this module is no
-exception. If you find a bug please either email me, or add the bug
-to cpan-RT.
+exception.
+
+Please report any bugs to C<bug-moose@rt.cpan.org>, or through the web
+interface at L<http://rt.cpan.org>.
=head1 FEATURE REQUESTS
-We are very strict about what features we add to the Moose core, especially
-the user-visible features. Instead we have made sure that the underlying
-meta-system of Moose is as extensible as possible so that you can add your
-own features easily. That said, occasionally there is a feature needed in the
-meta-system to support your planned extension, in which case you should
-either email the mailing list or join us on irc at #moose to discuss.
+We are very strict about what features we add to the Moose core, especially
+the user-visible features. Instead we have made sure that the underlying
+meta-system of Moose is as extensible as possible so that you can add your
+own features easily.
+
+That said, occasionally there is a feature needed in the meta-system
+to support your planned extension, in which case you should either
+email the mailing list (moose@perl.org) or join us on IRC at
+L<irc://irc.perl.org/#moose> to discuss. The
+L<Moose::Manual::Contributing> has more detail about how and when you
+can contribute.
=head1 AUTHOR
-Stevan Little E<lt>stevan@iinteractive.comE<gt>
+Moose is an open project, there are at this point dozens of people who have
+contributed, and can contribute. If you have added anything to the Moose
+project you have a commit bit on this file and can add your name to the list.
+
+=head2 CABAL
+
+However there are only a few people with the rights to release a new version
+of Moose. The Moose Cabal are the people to go to with questions regarding
+the wider purview of Moose, and help out maintaining not just the code
+but the community as well.
+
+Stevan (stevan) Little E<lt>stevan@iinteractive.comE<gt>
+
+Yuval (nothingmuch) Kogman
+
+Shawn (sartak) Moore E<lt>sartak@bestpractical.comE<gt>
+
+Dave (autarch) Rolsky E<lt>autarch@urth.orgE<gt>
+
+Jesse (doy) Luehrs E<lt>doy at tozt dot netE<gt>
-B<with contributions from:>
+Hans Dieter (confound) Pearcey E<lt>hdp@pobox.comE<gt>
+
+Chris (perigrin) Prather
+
+Florian Ragwitz E<lt>rafl@debian.orgE<gt>
+
+=head2 OTHER CONTRIBUTORS
Aankhen
Anders (Debolaz) Nor Berle
-Nathan (kolibre) Gray
+Nathan (kolibrie) Gray
Christian (chansen) Hansen
-Hans Dieter (confound) Pearcey
-
Eric (ewilhelm) Wilhelm
Guillermo (groditi) Roditi
Shlomi (rindolf) Fish
-Yuval (nothingmuch) Kogman
-
-Chris (perigrin) Prather
-
Wallace (wreis) Reis
Jonathan (jrockway) Rockway
-Dave (autarch) Rolsky
-
Piotr (dexter) Roszatycki
Sam (mugwump) Vilain
-Shawn (sartak) Moore
+Cory (gphat) Watson
+
+Dylan Hardison (doc fixes)
... and many other #moose folks
=head1 COPYRIGHT AND LICENSE
-Copyright 2006-2008 by Infinity Interactive, Inc.
+Copyright 2006-2009 by Infinity Interactive, Inc.
L<http://www.iinteractive.com>