=head1 NAME base - Establish IS-A relationship with base class at compile time =head1 SYNOPSIS package Baz; use base qw(Foo Bar); ## new usage allowed by podmaster, allows for require MODULE versionnumber; package Baz; use base { Foo => 1, 'Foo::Bar' => 2}; ## need quotes use base \%{{ BARE::WORD => 2}}; ## only works like this =head1 DESCRIPTION Roughly similar in effect to BEGIN { require Foo; require Bar; push @ISA, qw(Foo Bar); } Will also initialize the %FIELDS hash if one of the base classes has it. Multiple inheritance of %FIELDS is not supported. The 'base' pragma will croak if multiple base classes have a %FIELDS hash. See L for a description of this feature. When strict 'vars' is in scope I also let you assign to @ISA without having to declare @ISA with the 'vars' pragma first. If any of the base classes are not loaded yet, I silently Cs them. Whether to C a base class package is determined by the absence of a global $VERSION in the base package. If $VERSION is not detected even after loading it, will define $VERSION in the base package, setting it to the string C<-1, set by base.pm>. The new feature of this module, allows for version checking via use base { 'MODULE' => 33 }; # version 33 which is roughly equivalent to use MODULE 33; use base 'MODULE'; and will C much like C if version 33 of MODULE is not available =head1 HISTORY This module was introduced with Perl 5.004_04. =head1 SEE ALSO L =cut package base; use 5.006_001; our $VERSION = "1.02"; sub import { my $class = shift; my $fields_base; my $pkg = caller(0); my @bases = @_; ##podmaster - cause i don't wanna modify @bases my %BASV=(); ##podmaster if(ref $bases[0] eq 'HASH') { ##podmaster %BASV = %{$bases[0]}; @bases = keys %BASV; } foreach my $base (@bases) { ##podmaster next if $pkg->isa($base); push @{"$pkg\::ISA"}, $base; my $vglob; unless (${*{"$base\::VERSION"}{SCALAR}}) { eval "require $base"; # Only ignore "Can't locate" errors from our eval require. # Other fatal errors (syntax etc) must be reported. die if $@ && $@ !~ /^Can't locate .*? at \(eval /; unless (%{"$base\::"}) { require Carp; Carp::croak("Base class package \"$base\" is empty.\n", "\t(Perhaps you need to 'use' the module ", "which defines that package first.)"); } ${"$base\::VERSION"} = "-1, set by base.pm" unless ${*{"$base\::VERSION"}{SCALAR}}; } ##podmaster - allows for use base { module => versionnumber } if(%BASV and exists $BASV{$base} and $BASV{$base} > ${"${base}::VERSION"}) { ## wanted > available require Carp; Carp::croak("$base version $BASV{$base} required--this is only version " .${"${base}::VERSION"}); } # A simple test like (defined %{"$base\::FIELDS"}) will # sometimes produce typo warnings because it would create # the hash if it was not present before. my $fglob; if ($fglob = ${"$base\::"}{"FIELDS"} and *$fglob{HASH}) { if ($fields_base) { require Carp; Carp::croak("Can't multiply inherit %FIELDS"); } else { $fields_base = $base; } } } if ($fields_base) { require fields; fields::inherit($pkg, $fields_base); } } 1; #### #!/usr/bin/perl -w package GENERIC; use lib qw(.); use strict; BEGIN { use base 'CGI::Application'; # regular usage use base { 'CGI::Application' => 2.1 }; # new usage use base { # do the switch'a'roo to see an err message 'DBI' => 1, # 'DBI' => 16, }; } sub setup { my $self = shift; $self->start_mode('hi'); $self->mode_param('op'); $self->run_modes( hi => sub {" hi ".join(' ',caller())}, AUTOLOAD => sub {" hello ".join(' ',caller())}, ); } package main; my $DE_GENERIC = GENERIC->new(); $DE_GENERIC->run();