1b8851fccSafresh1use 5.008; 2b39c5158Smillertpackage base; 3b39c5158Smillert 4b39c5158Smillertuse strict 'vars'; 5*9f11ffb7Safresh1our $VERSION = '2.27'; 6b8851fccSafresh1$VERSION =~ tr/_//d; 7b39c5158Smillert 8cbfb5651Safresh1# simplest way to avoid indexing of the package: no package statement 9de18eedbSafresh1sub base::__inc::unhook { @INC = grep !(ref eq 'CODE' && $_ == $_[0]), @INC } 10de18eedbSafresh1# instance is blessed array of coderefs to be removed from @INC at scope exit 11de18eedbSafresh1sub base::__inc::scope_guard::DESTROY { base::__inc::unhook $_ for @{$_[0]} } 12cbfb5651Safresh1 13b39c5158Smillert# constant.pm is slow 14b39c5158Smillertsub SUCCESS () { 1 } 15b39c5158Smillert 16b39c5158Smillertsub PUBLIC () { 2**0 } 17b39c5158Smillertsub PRIVATE () { 2**1 } 18b39c5158Smillertsub INHERITED () { 2**2 } 19b39c5158Smillertsub PROTECTED () { 2**3 } 20b39c5158Smillert 21b39c5158Smillert 22b39c5158Smillertmy $Fattr = \%fields::attr; 23b39c5158Smillert 24b39c5158Smillertsub has_fields { 25b39c5158Smillert my($base) = shift; 26b39c5158Smillert my $fglob = ${"$base\::"}{FIELDS}; 27b39c5158Smillert return( ($fglob && 'GLOB' eq ref($fglob) && *$fglob{HASH}) ? 1 : 0 ); 28b39c5158Smillert} 29b39c5158Smillert 30b39c5158Smillertsub has_attr { 31b39c5158Smillert my($proto) = shift; 32b39c5158Smillert my($class) = ref $proto || $proto; 33b39c5158Smillert return exists $Fattr->{$class}; 34b39c5158Smillert} 35b39c5158Smillert 36b39c5158Smillertsub get_attr { 37b39c5158Smillert $Fattr->{$_[0]} = [1] unless $Fattr->{$_[0]}; 38b39c5158Smillert return $Fattr->{$_[0]}; 39b39c5158Smillert} 40b39c5158Smillert 41b39c5158Smillertif ($] < 5.009) { 42b39c5158Smillert *get_fields = sub { 43b39c5158Smillert # Shut up a possible typo warning. 44b39c5158Smillert () = \%{$_[0].'::FIELDS'}; 45b39c5158Smillert my $f = \%{$_[0].'::FIELDS'}; 46b39c5158Smillert 47b39c5158Smillert # should be centralized in fields? perhaps 48b39c5158Smillert # fields::mk_FIELDS_be_OK. Peh. As long as %{ $package . '::FIELDS' } 49b39c5158Smillert # is used here anyway, it doesn't matter. 50b39c5158Smillert bless $f, 'pseudohash' if (ref($f) ne 'pseudohash'); 51b39c5158Smillert 52b39c5158Smillert return $f; 53b39c5158Smillert } 54b39c5158Smillert} 55b39c5158Smillertelse { 56b39c5158Smillert *get_fields = sub { 57b39c5158Smillert # Shut up a possible typo warning. 58b39c5158Smillert () = \%{$_[0].'::FIELDS'}; 59b39c5158Smillert return \%{$_[0].'::FIELDS'}; 60b39c5158Smillert } 61b39c5158Smillert} 62b39c5158Smillert 636fb12b70Safresh1if ($] < 5.008) { 646fb12b70Safresh1 *_module_to_filename = sub { 656fb12b70Safresh1 (my $fn = $_[0]) =~ s!::!/!g; 666fb12b70Safresh1 $fn .= '.pm'; 676fb12b70Safresh1 return $fn; 686fb12b70Safresh1 } 696fb12b70Safresh1} 706fb12b70Safresh1else { 716fb12b70Safresh1 *_module_to_filename = sub { 726fb12b70Safresh1 (my $fn = $_[0]) =~ s!::!/!g; 736fb12b70Safresh1 $fn .= '.pm'; 746fb12b70Safresh1 utf8::encode($fn); 756fb12b70Safresh1 return $fn; 766fb12b70Safresh1 } 776fb12b70Safresh1} 786fb12b70Safresh1 796fb12b70Safresh1 80b39c5158Smillertsub import { 81b39c5158Smillert my $class = shift; 82b39c5158Smillert 83b39c5158Smillert return SUCCESS unless @_; 84b39c5158Smillert 85b39c5158Smillert # List of base classes from which we will inherit %FIELDS. 86b39c5158Smillert my $fields_base; 87b39c5158Smillert 88b39c5158Smillert my $inheritor = caller(0); 89b39c5158Smillert 90b39c5158Smillert my @bases; 91b39c5158Smillert foreach my $base (@_) { 92b39c5158Smillert if ( $inheritor eq $base ) { 93b39c5158Smillert warn "Class '$inheritor' tried to inherit from itself\n"; 94b39c5158Smillert } 95b39c5158Smillert 96b39c5158Smillert next if grep $_->isa($base), ($inheritor, @bases); 97b39c5158Smillert 98cbfb5651Safresh1 # Following blocks help isolate $SIG{__DIE__} and @INC changes 99898184e3Ssthen { 100b39c5158Smillert my $sigdie; 101b39c5158Smillert { 102b39c5158Smillert local $SIG{__DIE__}; 1036fb12b70Safresh1 my $fn = _module_to_filename($base); 104de18eedbSafresh1 my $dot_hidden; 105cbfb5651Safresh1 eval { 106de18eedbSafresh1 my $guard; 107de18eedbSafresh1 if ($INC[-1] eq '.' && %{"$base\::"}) { 108de18eedbSafresh1 # So: the package already exists => this an optional load 109de18eedbSafresh1 # And: there is a dot at the end of @INC => we want to hide it 110de18eedbSafresh1 # However: we only want to hide it during our *own* require() 111de18eedbSafresh1 # (i.e. without affecting nested require()s). 112de18eedbSafresh1 # So we add a hook to @INC whose job is to hide the dot, but which 113de18eedbSafresh1 # first checks checks the callstack depth, because within nested 114de18eedbSafresh1 # require()s the callstack is deeper. 115de18eedbSafresh1 # Since CORE::GLOBAL::require makes it unknowable in advance what 116de18eedbSafresh1 # the exact relevant callstack depth will be, we have to record it 117de18eedbSafresh1 # inside a hook. So we put another hook just for that at the front 118de18eedbSafresh1 # of @INC, where it's guaranteed to run -- immediately. 119de18eedbSafresh1 # The dot-hiding hook does its job by sitting directly in front of 120de18eedbSafresh1 # the dot and removing itself from @INC when reached. This causes 121de18eedbSafresh1 # the dot to move up one index in @INC, causing the loop inside 122de18eedbSafresh1 # pp_require() to skip it. 123de18eedbSafresh1 # Loaded coded may disturb this precise arrangement, but that's OK 124de18eedbSafresh1 # because the hook is inert by that time. It is only active during 125de18eedbSafresh1 # the top-level require(), when @INC is in our control. The only 126de18eedbSafresh1 # possible gotcha is if other hooks already in @INC modify @INC in 127de18eedbSafresh1 # some way during that initial require(). 128de18eedbSafresh1 # Note that this jiggery hookery works just fine recursively: if 129de18eedbSafresh1 # a module loaded via base.pm uses base.pm itself, there will be 130de18eedbSafresh1 # one pair of hooks in @INC per base::import call frame, but the 131de18eedbSafresh1 # pairs from different nestings do not interfere with each other. 132de18eedbSafresh1 my $lvl; 133de18eedbSafresh1 unshift @INC, sub { return if defined $lvl; 1 while defined caller ++$lvl; () }; 134de18eedbSafresh1 splice @INC, -1, 0, sub { return if defined caller $lvl; ++$dot_hidden, &base::__inc::unhook; () }; 135de18eedbSafresh1 $guard = bless [ @INC[0,-2] ], 'base::__inc::scope_guard'; 136de18eedbSafresh1 } 137cbfb5651Safresh1 require $fn 138cbfb5651Safresh1 }; 139de18eedbSafresh1 if ($dot_hidden && (my @fn = grep -e && !( -d _ || -b _ ), $fn.'c', $fn)) { 140de18eedbSafresh1 require Carp; 141de18eedbSafresh1 Carp::croak(<<ERROR); 142de18eedbSafresh1Base class package "$base" is not empty but "$fn[0]" exists in the current directory. 143de18eedbSafresh1 To help avoid security issues, base.pm now refuses to load optional modules 144de18eedbSafresh1 from the current working directory when it is the last entry in \@INC. 145de18eedbSafresh1 If your software worked on previous versions of Perl, the best solution 146de18eedbSafresh1 is to use FindBin to detect the path properly and to add that path to 147de18eedbSafresh1 \@INC. As a last resort, you can re-enable looking in the current working 148de18eedbSafresh1 directory by adding "use lib '.'" to your code. 149de18eedbSafresh1ERROR 150de18eedbSafresh1 } 151b39c5158Smillert # Only ignore "Can't locate" errors from our eval require. 152b39c5158Smillert # Other fatal errors (syntax etc) must be reported. 1536fb12b70Safresh1 # 1546fb12b70Safresh1 # changing the check here is fragile - if the check 1556fb12b70Safresh1 # here isn't catching every error you want, you should 1566fb12b70Safresh1 # probably be using parent.pm, which doesn't try to 1576fb12b70Safresh1 # guess whether require is needed or failed, 1586fb12b70Safresh1 # see [perl #118561] 1596fb12b70Safresh1 die if $@ && $@ !~ /^Can't locate \Q$fn\E .*? at .* line [0-9]+(?:, <[^>]*> (?:line|chunk) [0-9]+)?\.\n\z/s 1606fb12b70Safresh1 || $@ =~ /Compilation failed in require at .* line [0-9]+(?:, <[^>]*> (?:line|chunk) [0-9]+)?\.\n\z/; 161b39c5158Smillert unless (%{"$base\::"}) { 162b39c5158Smillert require Carp; 163b39c5158Smillert local $" = " "; 164de18eedbSafresh1 Carp::croak(<<ERROR); 165b39c5158SmillertBase class package "$base" is empty. 166b39c5158Smillert (Perhaps you need to 'use' the module which defines that package first, 167de18eedbSafresh1 or make that module available in \@INC (\@INC contains: @INC). 168b39c5158SmillertERROR 169b39c5158Smillert } 170b39c5158Smillert $sigdie = $SIG{__DIE__} || undef; 171b39c5158Smillert } 172b39c5158Smillert # Make sure a global $SIG{__DIE__} makes it out of the localization. 173b39c5158Smillert $SIG{__DIE__} = $sigdie if defined $sigdie; 174b39c5158Smillert } 175b39c5158Smillert push @bases, $base; 176b39c5158Smillert 177b39c5158Smillert if ( has_fields($base) || has_attr($base) ) { 178b39c5158Smillert # No multiple fields inheritance *suck* 179b39c5158Smillert if ($fields_base) { 180b39c5158Smillert require Carp; 181b39c5158Smillert Carp::croak("Can't multiply inherit fields"); 182b39c5158Smillert } else { 183b39c5158Smillert $fields_base = $base; 184b39c5158Smillert } 185b39c5158Smillert } 186b39c5158Smillert } 187b39c5158Smillert # Save this until the end so it's all or nothing if the above loop croaks. 188b39c5158Smillert push @{"$inheritor\::ISA"}, @bases; 189b39c5158Smillert 190b39c5158Smillert if( defined $fields_base ) { 191b39c5158Smillert inherit_fields($inheritor, $fields_base); 192b39c5158Smillert } 193b39c5158Smillert} 194b39c5158Smillert 195b39c5158Smillert 196b39c5158Smillertsub inherit_fields { 197b39c5158Smillert my($derived, $base) = @_; 198b39c5158Smillert 199b39c5158Smillert return SUCCESS unless $base; 200b39c5158Smillert 201b39c5158Smillert my $battr = get_attr($base); 202b39c5158Smillert my $dattr = get_attr($derived); 203b39c5158Smillert my $dfields = get_fields($derived); 204b39c5158Smillert my $bfields = get_fields($base); 205b39c5158Smillert 206b39c5158Smillert $dattr->[0] = @$battr; 207b39c5158Smillert 208b39c5158Smillert if( keys %$dfields ) { 209b39c5158Smillert warn <<"END"; 210b39c5158Smillert$derived is inheriting from $base but already has its own fields! 211b39c5158SmillertThis will cause problems. Be sure you use base BEFORE declaring fields. 212b39c5158SmillertEND 213b39c5158Smillert 214b39c5158Smillert } 215b39c5158Smillert 216b39c5158Smillert # Iterate through the base's fields adding all the non-private 217b39c5158Smillert # ones to the derived class. Hang on to the original attribute 218b39c5158Smillert # (Public, Private, etc...) and add Inherited. 219b39c5158Smillert # This is all too complicated to do efficiently with add_fields(). 220b39c5158Smillert while (my($k,$v) = each %$bfields) { 221b39c5158Smillert my $fno; 222b39c5158Smillert if ($fno = $dfields->{$k} and $fno != $v) { 223b39c5158Smillert require Carp; 224b39c5158Smillert Carp::croak ("Inherited fields can't override existing fields"); 225b39c5158Smillert } 226b39c5158Smillert 227b39c5158Smillert if( $battr->[$v] & PRIVATE ) { 228b39c5158Smillert $dattr->[$v] = PRIVATE | INHERITED; 229b39c5158Smillert } 230b39c5158Smillert else { 231b39c5158Smillert $dattr->[$v] = INHERITED | $battr->[$v]; 232b39c5158Smillert $dfields->{$k} = $v; 233b39c5158Smillert } 234b39c5158Smillert } 235b39c5158Smillert 236b39c5158Smillert foreach my $idx (1..$#{$battr}) { 237b39c5158Smillert next if defined $dattr->[$idx]; 238b39c5158Smillert $dattr->[$idx] = $battr->[$idx] & INHERITED; 239b39c5158Smillert } 240b39c5158Smillert} 241b39c5158Smillert 242b39c5158Smillert 243b39c5158Smillert1; 244b39c5158Smillert 245b39c5158Smillert__END__ 246b39c5158Smillert 247b39c5158Smillert=head1 NAME 248b39c5158Smillert 249b39c5158Smillertbase - Establish an ISA relationship with base classes at compile time 250b39c5158Smillert 251b39c5158Smillert=head1 SYNOPSIS 252b39c5158Smillert 253b39c5158Smillert package Baz; 254b39c5158Smillert use base qw(Foo Bar); 255b39c5158Smillert 256b39c5158Smillert=head1 DESCRIPTION 257b39c5158Smillert 258b39c5158SmillertUnless you are using the C<fields> pragma, consider this module discouraged 259b39c5158Smillertin favor of the lighter-weight C<parent>. 260b39c5158Smillert 261b39c5158SmillertAllows you to both load one or more modules, while setting up inheritance from 262b39c5158Smillertthose modules at the same time. Roughly similar in effect to 263b39c5158Smillert 264b39c5158Smillert package Baz; 265b39c5158Smillert BEGIN { 266b39c5158Smillert require Foo; 267b39c5158Smillert require Bar; 268b39c5158Smillert push @ISA, qw(Foo Bar); 269b39c5158Smillert } 270b39c5158Smillert 271898184e3SsthenWhen C<base> tries to C<require> a module, it will not die if it cannot find 272898184e3Ssthenthe module's file, but will die on any other error. After all this, should 273898184e3Ssthenyour base class be empty, containing no symbols, C<base> will die. This is 274898184e3Ssthenuseful for inheriting from classes in the same file as yourself but where 275898184e3Ssthenthe filename does not match the base module name, like so: 276b39c5158Smillert 277898184e3Ssthen # in Bar.pm 278b39c5158Smillert package Foo; 279b39c5158Smillert sub exclaim { "I can have such a thing?!" } 280b39c5158Smillert 281b39c5158Smillert package Bar; 282b39c5158Smillert use base "Foo"; 283b39c5158Smillert 284898184e3SsthenThere is no F<Foo.pm>, but because C<Foo> defines a symbol (the C<exclaim> 285898184e3Ssthensubroutine), C<base> will not die when the C<require> fails to load F<Foo.pm>. 286b39c5158Smillert 287b39c5158SmillertC<base> will also initialize the fields if one of the base classes has it. 288b39c5158SmillertMultiple inheritance of fields is B<NOT> supported, if two or more base classes 289898184e3Sstheneach have inheritable fields the 'base' pragma will croak. See L<fields> 290898184e3Ssthenfor a description of this feature. 291b39c5158Smillert 292b39c5158SmillertThe base class' C<import> method is B<not> called. 293b39c5158Smillert 294b39c5158Smillert 295b39c5158Smillert=head1 DIAGNOSTICS 296b39c5158Smillert 297b39c5158Smillert=over 4 298b39c5158Smillert 299b39c5158Smillert=item Base class package "%s" is empty. 300b39c5158Smillert 301b39c5158Smillertbase.pm was unable to require the base package, because it was not 302b39c5158Smillertfound in your path. 303b39c5158Smillert 304b39c5158Smillert=item Class 'Foo' tried to inherit from itself 305b39c5158Smillert 306b39c5158SmillertAttempting to inherit from yourself generates a warning. 307b39c5158Smillert 308898184e3Ssthen package Foo; 309b39c5158Smillert use base 'Foo'; 310b39c5158Smillert 311b39c5158Smillert=back 312b39c5158Smillert 313b39c5158Smillert=head1 HISTORY 314b39c5158Smillert 315b39c5158SmillertThis module was introduced with Perl 5.004_04. 316b39c5158Smillert 317b39c5158Smillert=head1 CAVEATS 318b39c5158Smillert 319b39c5158SmillertDue to the limitations of the implementation, you must use 320b39c5158Smillertbase I<before> you declare any of your own fields. 321b39c5158Smillert 322b39c5158Smillert 323b39c5158Smillert=head1 SEE ALSO 324b39c5158Smillert 325b39c5158SmillertL<fields> 326b39c5158Smillert 327b39c5158Smillert=cut 328