bump version to 0.91
[gitmo/Moose.git] / lib / Moose / Exporter.pm
CommitLineData
e606ae5f 1package Moose::Exporter;
2
3use strict;
4use warnings;
5
113d3174 6our $VERSION = '0.91';
ae18d5ec 7$VERSION = eval $VERSION;
8our $AUTHORITY = 'cpan:STEVAN';
9
e606ae5f 10use Class::MOP;
11use List::MoreUtils qw( first_index uniq );
12use Moose::Util::MetaRole;
091ac4b7 13use Sub::Exporter 0.980;
9f2230e9 14use Sub::Name qw(subname);
e606ae5f 15
16my %EXPORT_SPEC;
17
18sub setup_import_methods {
19 my ( $class, %args ) = @_;
20
21 my $exporting_package = $args{exporting_package} ||= caller();
22
95056a1e 23 $class->build_import_methods(
24 %args,
25 install => [qw(import unimport init_meta)]
26 );
e606ae5f 27}
28
29sub build_import_methods {
30 my ( $class, %args ) = @_;
31
32 my $exporting_package = $args{exporting_package} ||= caller();
33
34 $EXPORT_SPEC{$exporting_package} = \%args;
35
36 my @exports_from = $class->_follow_also( $exporting_package );
37
38 my $export_recorder = {};
39
0661fc1a 40 my ( $exports, $is_removable )
e05fb8ae 41 = $class->_make_sub_exporter_params(
f44ec924 42 [ @exports_from, $exporting_package ], $export_recorder );
e606ae5f 43
44 my $exporter = Sub::Exporter::build_exporter(
45 {
46 exports => $exports,
0661fc1a 47 groups => { default => [':all'] }
e606ae5f 48 }
49 );
50
95056a1e 51 my %methods;
e606ae5f 52 # $args{_export_to_main} exists for backwards compat, because
53 # Moose::Util::TypeConstraints did export to main (unlike Moose &
54 # Moose::Role).
95056a1e 55 $methods{import} = $class->_make_import_sub( $exporting_package,
56 $exporter, \@exports_from, $args{_export_to_main} );
e606ae5f 57
95056a1e 58 $methods{unimport} = $class->_make_unimport_sub( $exporting_package,
59 $exports, $is_removable, $export_recorder );
60
61 $methods{init_meta} = $class->_make_init_meta( $exporting_package,
62 \%args );
63
64 my $package = Class::MOP::Package->initialize($exporting_package);
906eabcd 65 for my $to_install ( @{ $args{install} || [] } ) {
95056a1e 66 my $symbol = '&' . $to_install;
906eabcd 67 next
68 unless $methods{$to_install}
69 && !$package->has_package_symbol($symbol);
70 $package->add_package_symbol( $symbol, $methods{$to_install} );
95056a1e 71 }
e606ae5f 72
95056a1e 73 return ( $methods{import}, $methods{unimport}, $methods{init_meta} )
e606ae5f 74}
75
76{
77 my $seen = {};
78
79 sub _follow_also {
80 my $class = shift;
81 my $exporting_package = shift;
82
83 local %$seen = ( $exporting_package => 1 );
84
85 return uniq( _follow_also_real($exporting_package) );
86 }
87
88 sub _follow_also_real {
89 my $exporting_package = shift;
90
ba1a3c2f 91 if (!exists $EXPORT_SPEC{$exporting_package}) {
92 my $loaded = Class::MOP::is_class_loaded($exporting_package);
93
94 die "Package in also ($exporting_package) does not seem to "
95 . "use Moose::Exporter"
96 . ($loaded ? "" : " (is it loaded?)");
97 }
e606ae5f 98
99 my $also = $EXPORT_SPEC{$exporting_package}{also};
100
101 return unless defined $also;
102
103 my @also = ref $also ? @{$also} : $also;
104
105 for my $package (@also)
106 {
b822369d 107 die "Circular reference in 'also' parameter to Moose::Exporter between $exporting_package and $package"
e606ae5f 108 if $seen->{$package};
109
110 $seen->{$package} = 1;
111 }
112
113 return @also, map { _follow_also_real($_) } @also;
114 }
115}
116
117sub _make_sub_exporter_params {
118 my $class = shift;
119 my $packages = shift;
120 my $export_recorder = shift;
121
122 my %exports;
e05fb8ae 123 my %is_removable;
e606ae5f 124
125 for my $package ( @{$packages} ) {
126 my $args = $EXPORT_SPEC{$package}
127 or die "The $package package does not use Moose::Exporter\n";
128
5ac14e89 129 for my $name ( @{ $args->{with_meta} } ) {
0dd4228e 130 my $sub = $class->_sub_from_package( $package, $name )
131 or next;
e6a5040f 132
e606ae5f 133 my $fq_name = $package . '::' . $name;
134
5ac14e89 135 $exports{$name} = $class->_make_wrapped_sub_with_meta(
e606ae5f 136 $fq_name,
137 $sub,
138 $export_recorder,
139 );
e05fb8ae 140
141 $is_removable{$name} = 1;
e606ae5f 142 }
143
5ac14e89 144 for my $name ( @{ $args->{with_caller} } ) {
0dd4228e 145 my $sub = $class->_sub_from_package( $package, $name )
146 or next;
e6a5040f 147
45975bce 148 my $fq_name = $package . '::' . $name;
149
5ac14e89 150 $exports{$name} = $class->_make_wrapped_sub(
45975bce 151 $fq_name,
152 $sub,
153 $export_recorder,
154 );
155
156 $is_removable{$name} = 1;
157 }
158
e606ae5f 159 for my $name ( @{ $args->{as_is} } ) {
e6a5040f 160 my ($sub, $coderef_name);
e606ae5f 161
162 if ( ref $name ) {
163 $sub = $name;
e05fb8ae 164
165 # Even though Moose re-exports things from Carp &
166 # Scalar::Util, we don't want to remove those at
167 # unimport time, because the importing package may
168 # have imported them explicitly ala
169 #
170 # use Carp qw( confess );
171 #
172 # This is a hack. Since we can't know whether they
173 # really want to keep these subs or not, we err on the
174 # safe side and leave them in.
175 my $coderef_pkg;
e6a5040f 176 ( $coderef_pkg, $coderef_name )
177 = Class::MOP::get_code_info($name);
e05fb8ae 178
e6a5040f 179 $is_removable{$coderef_name} = $coderef_pkg eq $package ? 1 : 0;
e606ae5f 180 }
181 else {
0dd4228e 182 $sub = $class->_sub_from_package( $package, $name )
183 or next;
e6a5040f 184
e05fb8ae 185 $is_removable{$name} = 1;
e6a5040f 186 $coderef_name = $name;
e606ae5f 187 }
188
189 $export_recorder->{$sub} = 1;
190
e6a5040f 191 $exports{$coderef_name} = sub {$sub};
e606ae5f 192 }
193 }
194
0661fc1a 195 return ( \%exports, \%is_removable );
e606ae5f 196}
197
0dd4228e 198sub _sub_from_package {
199 my $sclass = shift;
200 my $package = shift;
201 my $name = shift;
202
203 my $sub = do {
204 no strict 'refs';
205 \&{ $package . '::' . $name };
206 };
207
208 return $sub if defined &$sub;
209
210 Carp::cluck
211 "Trying to export undefined sub ${package}::${name}";
212
213 return;
214}
215
96bb13ea 216our $CALLER;
217
218sub _make_wrapped_sub {
b4f00a34 219 my $self = shift;
96bb13ea 220 my $fq_name = shift;
221 my $sub = shift;
222 my $export_recorder = shift;
223
224 # We need to set the package at import time, so that when
225 # package Foo imports has(), we capture "Foo" as the
226 # package. This lets other packages call Foo::has() and get
227 # the right package. This is done for backwards compatibility
228 # with existing production code, not because this is a good
229 # idea ;)
230 return sub {
231 my $caller = $CALLER;
232
6de00734 233 my $wrapper = $self->_curry_wrapper($sub, $fq_name, $caller);
b4f00a34 234
9f2230e9 235 my $sub = subname($fq_name => $wrapper);
96bb13ea 236
237 $export_recorder->{$sub} = 1;
238
239 return $sub;
240 };
241}
e606ae5f 242
45975bce 243sub _make_wrapped_sub_with_meta {
244 my $self = shift;
245 my $fq_name = shift;
246 my $sub = shift;
247 my $export_recorder = shift;
248
249 return sub {
250 my $caller = $CALLER;
251
252 my $wrapper = $self->_late_curry_wrapper($sub, $fq_name,
253 sub { Class::MOP::class_of(shift) } => $caller);
254
255 my $sub = subname($fq_name => $wrapper);
256
257 $export_recorder->{$sub} = 1;
258
259 return $sub;
260 };
261}
262
6de00734 263sub _curry_wrapper {
badbc528 264 my $class = shift;
b4f00a34 265 my $sub = shift;
266 my $fq_name = shift;
6de00734 267 my @extra = @_;
b4f00a34 268
6de00734 269 my $wrapper = sub { $sub->(@extra, @_) };
badbc528 270 if (my $proto = prototype $sub) {
2d7e979b 271 # XXX - Perl's prototype sucks. Use & to make set_prototype
6de00734 272 # ignore the fact that we're passing "private variables"
2d7e979b 273 &Scalar::Util::set_prototype($wrapper, $proto);
badbc528 274 }
275 return $wrapper;
b4f00a34 276}
277
45975bce 278sub _late_curry_wrapper {
279 my $class = shift;
280 my $sub = shift;
281 my $fq_name = shift;
282 my $extra = shift;
283 my @ex_args = @_;
284
285 my $wrapper = sub {
286 # resolve curried arguments at runtime via this closure
287 my @curry = ( $extra->( @ex_args ) );
288 return $sub->(@curry, @_);
289 };
290
291 if (my $proto = prototype $sub) {
292 # XXX - Perl's prototype sucks. Use & to make set_prototype
293 # ignore the fact that we're passing "private variables"
294 &Scalar::Util::set_prototype($wrapper, $proto);
295 }
296 return $wrapper;
297}
298
96bb13ea 299sub _make_import_sub {
300 shift;
301 my $exporting_package = shift;
302 my $exporter = shift;
303 my $exports_from = shift;
304 my $export_to_main = shift;
305
306 return sub {
307
308 # I think we could use Sub::Exporter's collector feature
309 # to do this, but that would be rather gross, since that
310 # feature isn't really designed to return a value to the
311 # caller of the exporter sub.
312 #
313 # Also, this makes sure we preserve backwards compat for
314 # _get_caller, so it always sees the arguments in the
315 # expected order.
316 my $traits;
317 ( $traits, @_ ) = _strip_traits(@_);
318
8f30b86e 319 my $metaclass;
320 ( $metaclass, @_ ) = _strip_metaclass(@_);
8a8856de 321 $metaclass = Moose::Util::resolve_metaclass_alias(
322 'Class' => $metaclass
323 ) if defined $metaclass && length $metaclass;
8f30b86e 324
96bb13ea 325 # Normally we could look at $_[0], but in some weird cases
326 # (involving goto &Moose::import), $_[0] ends as something
327 # else (like Squirrel).
328 my $class = $exporting_package;
329
330 $CALLER = _get_caller(@_);
331
332 # this works because both pragmas set $^H (see perldoc
333 # perlvar) which affects the current compilation -
334 # i.e. the file who use'd us - which is why we don't need
335 # to do anything special to make it affect that file
336 # rather than this one (which is already compiled)
337
338 strict->import;
339 warnings->import;
340
341 # we should never export to main
342 if ( $CALLER eq 'main' && !$export_to_main ) {
343 warn
344 qq{$class does not export its sugar to the 'main' package.\n};
345 return;
346 }
e606ae5f 347
96bb13ea 348 my $did_init_meta;
349 for my $c ( grep { $_->can('init_meta') } $class, @{$exports_from} ) {
816208bc 350 # init_meta can apply a role, which when loaded uses
351 # Moose::Exporter, which in turn sets $CALLER, so we need
352 # to protect against that.
fdeb8354 353 local $CALLER = $CALLER;
89bcd625 354 $c->init_meta( for_class => $CALLER, metaclass => $metaclass );
96bb13ea 355 $did_init_meta = 1;
356 }
e606ae5f 357
96bb13ea 358 if ( $did_init_meta && @{$traits} ) {
359 # The traits will use Moose::Role, which in turn uses
360 # Moose::Exporter, which in turn sets $CALLER, so we need
361 # to protect against that.
362 local $CALLER = $CALLER;
363 _apply_meta_traits( $CALLER, $traits );
364 }
365 elsif ( @{$traits} ) {
70ea9161 366 require Moose;
96bb13ea 367 Moose->throw_error(
368 "Cannot provide traits when $class does not have an init_meta() method"
369 );
370 }
e606ae5f 371
96bb13ea 372 goto $exporter;
373 };
e606ae5f 374}
375
96bb13ea 376
e606ae5f 377sub _strip_traits {
378 my $idx = first_index { $_ eq '-traits' } @_;
379
380 return ( [], @_ ) unless $idx >= 0 && $#_ >= $idx + 1;
381
382 my $traits = $_[ $idx + 1 ];
383
384 splice @_, $idx, 2;
385
386 $traits = [ $traits ] unless ref $traits;
387
388 return ( $traits, @_ );
389}
390
8f30b86e 391sub _strip_metaclass {
392 my $idx = first_index { $_ eq '-metaclass' } @_;
393
394 return ( undef, @_ ) unless $idx >= 0 && $#_ >= $idx + 1;
395
396 my $metaclass = $_[ $idx + 1 ];
397
398 splice @_, $idx, 2;
399
400 return ( $metaclass, @_ );
401}
402
e606ae5f 403sub _apply_meta_traits {
404 my ( $class, $traits ) = @_;
405
406 return unless @{$traits};
407
2571a16d 408 my $meta = Class::MOP::class_of($class);
e606ae5f 409
410 my $type = ( split /::/, ref $meta )[-1]
c245d69b 411 or Moose->throw_error(
e606ae5f 412 'Cannot determine metaclass type for trait application . Meta isa '
4c0b3599 413 . ref $meta );
e606ae5f 414
415 my @resolved_traits
386c056b 416 = map {
417 ref $_ ? $_ : Moose::Util::resolve_metatrait_alias( $type => $_ )
418 }
e606ae5f 419 @$traits;
420
421 return unless @resolved_traits;
422
423 Moose::Util::MetaRole::apply_metaclass_roles(
424 for_class => $class,
425 metaclass_roles => \@resolved_traits,
426 );
427}
428
429sub _get_caller {
430 # 1 extra level because it's called by import so there's a layer
431 # of indirection
432 my $offset = 1;
433
434 return
435 ( ref $_[1] && defined $_[1]->{into} ) ? $_[1]->{into}
436 : ( ref $_[1] && defined $_[1]->{into_level} )
437 ? caller( $offset + $_[1]->{into_level} )
438 : caller($offset);
439}
440
441sub _make_unimport_sub {
442 shift;
443 my $exporting_package = shift;
444 my $exports = shift;
e05fb8ae 445 my $is_removable = shift;
e606ae5f 446 my $export_recorder = shift;
447
448 return sub {
449 my $caller = scalar caller();
450 Moose::Exporter->_remove_keywords(
451 $caller,
452 [ keys %{$exports} ],
e05fb8ae 453 $is_removable,
e606ae5f 454 $export_recorder,
455 );
456 };
457}
458
459sub _remove_keywords {
460 shift;
461 my $package = shift;
462 my $keywords = shift;
e05fb8ae 463 my $is_removable = shift;
e606ae5f 464 my $recorded_exports = shift;
465
466 no strict 'refs';
467
468 foreach my $name ( @{ $keywords } ) {
e05fb8ae 469 next unless $is_removable->{$name};
e606ae5f 470
471 if ( defined &{ $package . '::' . $name } ) {
472 my $sub = \&{ $package . '::' . $name };
473
474 # make sure it is from us
475 next unless $recorded_exports->{$sub};
476
477 # and if it is from us, then undef the slot
478 delete ${ $package . '::' }{$name};
479 }
480 }
481}
482
95056a1e 483sub _make_init_meta {
484 shift;
906eabcd 485 my $class = shift;
486 my $args = shift;
95056a1e 487
488 my %metaclass_roles;
906eabcd 489 for my $role (
490 map {"${_}_roles"}
491 qw(metaclass
492 attribute_metaclass
493 method_metaclass
494 wrapped_method_metaclass
495 instance_metaclass
496 constructor_class
497 destructor_class
498 error_class
499 application_to_class_class
500 application_to_role_class
501 application_to_instance_class)
502 ) {
95056a1e 503 $metaclass_roles{$role} = $args->{$role} if exists $args->{$role};
504 }
505
506 my %base_class_roles;
906eabcd 507 %base_class_roles = ( roles => $args->{base_class_roles} )
95056a1e 508 if exists $args->{base_class_roles};
509
510 return unless %metaclass_roles || %base_class_roles;
511
512 return sub {
513 shift;
514 my %options = @_;
906eabcd 515
516 return unless Class::MOP::class_of( $options{for_class} );
517
95056a1e 518 Moose::Util::MetaRole::apply_metaclass_roles(
519 for_class => $options{for_class},
520 %metaclass_roles,
521 );
906eabcd 522
95056a1e 523 Moose::Util::MetaRole::apply_base_class_roles(
524 for_class => $options{for_class},
525 %base_class_roles,
906eabcd 526 )
527 if Class::MOP::class_of( $options{for_class} )
528 ->isa('Moose::Meta::Class');
529
530 return Class::MOP::class_of( $options{for_class} );
95056a1e 531 };
532}
533
e2fa092d 534sub import {
535 strict->import;
536 warnings->import;
537}
538
e606ae5f 5391;
540
541__END__
542
543=head1 NAME
544
545Moose::Exporter - make an import() and unimport() just like Moose.pm
546
547=head1 SYNOPSIS
548
549 package MyApp::Moose;
550
e606ae5f 551 use Moose ();
552 use Moose::Exporter;
553
554 Moose::Exporter->setup_import_methods(
5ac14e89 555 with_meta => [ 'has_rw', 'sugar2' ],
556 as_is => [ 'sugar3', \&Some::Random::thing ],
557 also => 'Moose',
e606ae5f 558 );
559
82ad7804 560 sub has_rw {
5ac14e89 561 my ( $meta, $name, %options ) = @_;
562 $meta->add_attribute(
563 $name,
82ad7804 564 is => 'rw',
565 %options,
566 );
567 }
568
e606ae5f 569 # then later ...
570 package MyApp::User;
571
572 use MyApp::Moose;
573
574 has 'name';
6daad0b9 575 has_rw 'size';
e606ae5f 576 thing;
577
578 no MyApp::Moose;
579
580=head1 DESCRIPTION
581
fd7ab111 582This module encapsulates the exporting of sugar functions in a
95056a1e 583C<Moose.pm>-like manner. It does this by building custom C<import>,
37e4fe95 584C<unimport>, and C<init_meta> methods for your module, based on a spec you
585provide.
e606ae5f 586
37e4fe95 587It also lets you "stack" Moose-alike modules so you can export Moose's sugar
588as well as your own, along with sugar from any random C<MooseX> module, as
589long as they all use C<Moose::Exporter>. This feature exists to let you bundle
590a set of MooseX modules into a policy module that developers can use directly
591instead of using Moose itself.
e606ae5f 592
10e0127a 593To simplify writing exporter modules, C<Moose::Exporter> also imports
594C<strict> and C<warnings> into your exporter module, as well as into
595modules that use it.
596
e606ae5f 597=head1 METHODS
598
599This module provides two public methods:
600
4b68e0de 601=over 4
602
603=item B<< Moose::Exporter->setup_import_methods(...) >>
e606ae5f 604
95056a1e 605When you call this method, C<Moose::Exporter> builds custom C<import>,
37e4fe95 606C<unimport>, and C<init_meta> methods for your module. The C<import> method
607will export the functions you specify, and can also re-export functions
608exported by some other module (like C<Moose.pm>).
e606ae5f 609
37e4fe95 610The C<unimport> method cleans the caller's namespace of all the exported
611functions.
e606ae5f 612
37e4fe95 613If you pass any parameters for L<Moose::Util::MetaRole>, this method will
614generate an C<init_meta> for you as well (see below for details). This
615C<init_meta> will call C<Moose::Util::MetaRole::apply_metaclass_roles> and
616C<Moose::Util::MetaRole::apply_base_class_roles> as needed.
95056a1e 617
618Note that if any of these methods already exist, they will not be
619overridden, you will have to use C<build_import_methods> to get the
620coderef that would be installed.
e606ae5f 621
622This method accepts the following parameters:
623
4b68e0de 624=over 8
e606ae5f 625
5ac14e89 626=item * with_meta => [ ... ]
e606ae5f 627
37e4fe95 628This list of function I<names only> will be wrapped and then exported. The
5ac14e89 629wrapper will pass the metaclass object for the caller as its first argument.
630
631Many sugar functions will need to use this metaclass object to do something to
632the calling package.
e606ae5f 633
634=item * as_is => [ ... ]
635
37e4fe95 636This list of function names or sub references will be exported as-is. You can
637identify a subroutine by reference, which is handy to re-export some other
638module's functions directly by reference (C<\&Some::Package::function>).
e606ae5f 639
37e4fe95 640If you do export some other package's function, this function will never be
641removed by the C<unimport> method. The reason for this is we cannot know if
642the caller I<also> explicitly imported the sub themselves, and therefore wants
643to keep it.
e05fb8ae 644
e606ae5f 645=item * also => $name or \@names
646
647This is a list of modules which contain functions that the caller
648wants to export. These modules must also use C<Moose::Exporter>. The
649most common use case will be to export the functions from C<Moose.pm>.
5ac14e89 650Functions specified by C<with_meta> or C<as_is> take precedence over
ae8817b6 651functions exported by modules specified by C<also>, so that a module
652can selectively override functions exported by another module.
e606ae5f 653
654C<Moose::Exporter> also makes sure all these functions get removed
655when C<unimport> is called.
656
657=back
658
95056a1e 659Any of the C<*_roles> options for
37e4fe95 660C<Moose::Util::MetaRole::apply_metaclass_roles> and
661C<Moose::Util::MetaRole::base_class_roles> are also acceptable.
95056a1e 662
4b68e0de 663=item B<< Moose::Exporter->build_import_methods(...) >>
e606ae5f 664
95056a1e 665Returns two or three code refs, one for C<import>, one for
666C<unimport>, and optionally one for C<init_meta>, if the appropriate
667options are passed in.
668
37e4fe95 669Accepts the additional C<install> option, which accepts an arrayref of method
670names to install into your exporting package. The valid options are C<import>,
671C<unimport>, and C<init_meta>. Calling C<setup_import_methods> is equivalent
672to calling C<build_import_methods> with C<< install => [qw(import unimport
673init_meta)] >> except that it doesn't also return the methods.
e606ae5f 674
675Used by C<setup_import_methods>.
676
4b68e0de 677=back
678
e606ae5f 679=head1 IMPORTING AND init_meta
680
37e4fe95 681If you want to set an alternative base object class or metaclass class, see
682above for details on how this module can call L<Moose::Util::MetaRole> for
683you.
684
685If you want to do something that is not supported by this module, simply
686define an C<init_meta> method in your class. The C<import> method that
687C<Moose::Exporter> generates for you will call this method (if it exists). It
688will always pass the caller to this method via the C<for_class> parameter.
e606ae5f 689
690Most of the time, your C<init_meta> method will probably just call C<<
691Moose->init_meta >> to do the real work:
692
693 sub init_meta {
694 shift; # our class name
695 return Moose->init_meta( @_, metaclass => 'My::Metaclass' );
696 }
697
95056a1e 698Keep in mind that C<build_import_methods> will return an C<init_meta>
699method for you, which you can also call from within your custom
37e4fe95 700C<init_meta>:
701
702 my ( $import, $unimport, $init_meta ) =
703 Moose::Exporter->build_import_methods( ... );
704
705 sub import {
706 my $class = shift;
707
708 ...
709
710 $class->$import(...);
711
712 ...
713 }
714
715 sub unimport { goto &$unimport }
716
717 sub init_meta {
718 my $class = shift;
719
720 ...
721
722 $class->$init_meta(...);
723
724 ...
725 }
95056a1e 726
e606ae5f 727=head1 METACLASS TRAITS
728
729The C<import> method generated by C<Moose::Exporter> will allow the
730user of your module to specify metaclass traits in a C<-traits>
731parameter passed as part of the import:
732
733 use Moose -traits => 'My::Meta::Trait';
734
735 use Moose -traits => [ 'My::Meta::Trait', 'My::Other::Trait' ];
736
737These traits will be applied to the caller's metaclass
738instance. Providing traits for an exporting class that does not create
739a metaclass for the caller is an error.
740
741=head1 AUTHOR
742
743Dave Rolsky E<lt>autarch@urth.orgE<gt>
744
745This is largely a reworking of code in Moose.pm originally written by
746Stevan Little and others.
747
748=head1 COPYRIGHT AND LICENSE
749
2840a3b2 750Copyright 2009 by Infinity Interactive, Inc.
e606ae5f 751
752L<http://www.iinteractive.com>
753
754This library is free software; you can redistribute it and/or modify
755it under the same terms as Perl itself.
756
757=cut