home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / share / perl / 5.10.1 / base.pm < prev    next >
Encoding:
Perl POD Document  |  2012-12-11  |  4.8 KB  |  182 lines

  1. package base;
  2.  
  3. use strict 'vars';
  4. use vars qw($VERSION);
  5. $VERSION = '2.14';
  6. $VERSION = eval $VERSION;
  7.  
  8. # constant.pm is slow
  9. sub SUCCESS () { 1 }
  10.  
  11. sub PUBLIC     () { 2**0  }
  12. sub PRIVATE    () { 2**1  }
  13. sub INHERITED  () { 2**2  }
  14. sub PROTECTED  () { 2**3  }
  15.  
  16. my $Fattr = \%fields::attr;
  17.  
  18. sub has_fields {
  19.     my($base) = shift;
  20.     my $fglob = ${"$base\::"}{FIELDS};
  21.     return( ($fglob && 'GLOB' eq ref($fglob) && *$fglob{HASH}) ? 1 : 0 );
  22. }
  23.  
  24. sub has_version {
  25.     my($base) = shift;
  26.     my $vglob = ${$base.'::'}{VERSION};
  27.     return( ($vglob && *$vglob{SCALAR}) ? 1 : 0 );
  28. }
  29.  
  30. sub has_attr {
  31.     my($proto) = shift;
  32.     my($class) = ref $proto || $proto;
  33.     return exists $Fattr->{$class};
  34. }
  35.  
  36. sub get_attr {
  37.     $Fattr->{$_[0]} = [1] unless $Fattr->{$_[0]};
  38.     return $Fattr->{$_[0]};
  39. }
  40.  
  41. if ($] < 5.009) {
  42.     *get_fields = sub {
  43.         # Shut up a possible typo warning.
  44.         () = \%{$_[0].'::FIELDS'};
  45.         my $f = \%{$_[0].'::FIELDS'};
  46.  
  47.         # should be centralized in fields? perhaps
  48.         # fields::mk_FIELDS_be_OK. Peh. As long as %{ $package . '::FIELDS' }
  49.         # is used here anyway, it doesn't matter.
  50.         bless $f, 'pseudohash' if (ref($f) ne 'pseudohash');
  51.  
  52.         return $f;
  53.     }
  54. }
  55. else {
  56.     *get_fields = sub {
  57.         # Shut up a possible typo warning.
  58.         () = \%{$_[0].'::FIELDS'};
  59.         return \%{$_[0].'::FIELDS'};
  60.     }
  61. }
  62.  
  63. sub import {
  64.     my $class = shift;
  65.  
  66.     return SUCCESS unless @_;
  67.  
  68.     # List of base classes from which we will inherit %FIELDS.
  69.     my $fields_base;
  70.  
  71.     my $inheritor = caller(0);
  72.     my @isa_classes;
  73.  
  74.     my @bases;
  75.     foreach my $base (@_) {
  76.         if ( $inheritor eq $base ) {
  77.             warn "Class '$inheritor' tried to inherit from itself\n";
  78.         }
  79.  
  80.         next if grep $_->isa($base), ($inheritor, @bases);
  81.  
  82.         if (has_version($base)) {
  83.             ${$base.'::VERSION'} = '-1, set by base.pm' 
  84.               unless defined ${$base.'::VERSION'};
  85.         }
  86.         else {
  87.             my $sigdie;
  88.             {
  89.                 local $SIG{__DIE__};
  90.                 eval "require $base";
  91.                 # Only ignore "Can't locate" errors from our eval require.
  92.                 # Other fatal errors (syntax etc) must be reported.
  93.                 die if $@ && $@ !~ /^Can't locate .*? at \(eval /;
  94.                 unless (%{"$base\::"}) {
  95.                     require Carp;
  96.                     local $" = " ";
  97.                     Carp::croak(<<ERROR);
  98. Base class package "$base" is empty.
  99.     (Perhaps you need to 'use' the module which defines that package first,
  100.     or make that module available in \@INC (\@INC contains: @INC).
  101. ERROR
  102.                 }
  103.                 $sigdie = $SIG{__DIE__} || undef;
  104.             }
  105.             # Make sure a global $SIG{__DIE__} makes it out of the localization.
  106.             $SIG{__DIE__} = $sigdie if defined $sigdie;
  107.             ${$base.'::VERSION'} = "-1, set by base.pm"
  108.               unless defined ${$base.'::VERSION'};
  109.         }
  110.         push @bases, $base;
  111.  
  112.         if ( has_fields($base) || has_attr($base) ) {
  113.             # No multiple fields inheritance *suck*
  114.             if ($fields_base) {
  115.                 require Carp;
  116.                 Carp::croak("Can't multiply inherit fields");
  117.             } else {
  118.                 $fields_base = $base;
  119.             }
  120.         }
  121.     }
  122.     # Save this until the end so it's all or nothing if the above loop croaks.
  123.     push @{"$inheritor\::ISA"}, @isa_classes;
  124.  
  125.     push @{"$inheritor\::ISA"}, @bases;
  126.  
  127.     if( defined $fields_base ) {
  128.         inherit_fields($inheritor, $fields_base);
  129.     }
  130. }
  131.  
  132. sub inherit_fields {
  133.     my($derived, $base) = @_;
  134.  
  135.     return SUCCESS unless $base;
  136.  
  137.     my $battr = get_attr($base);
  138.     my $dattr = get_attr($derived);
  139.     my $dfields = get_fields($derived);
  140.     my $bfields = get_fields($base);
  141.  
  142.     $dattr->[0] = @$battr;
  143.  
  144.     if( keys %$dfields ) {
  145.         warn <<"END";
  146. $derived is inheriting from $base but already has its own fields!
  147. This will cause problems.  Be sure you use base BEFORE declaring fields.
  148. END
  149.  
  150.     }
  151.  
  152.     # Iterate through the base's fields adding all the non-private
  153.     # ones to the derived class.  Hang on to the original attribute
  154.     # (Public, Private, etc...) and add Inherited.
  155.     # This is all too complicated to do efficiently with add_fields().
  156.     while (my($k,$v) = each %$bfields) {
  157.         my $fno;
  158.         if ($fno = $dfields->{$k} and $fno != $v) {
  159.             require Carp;
  160.             Carp::croak ("Inherited fields can't override existing fields");
  161.         }
  162.  
  163.         if( $battr->[$v] & PRIVATE ) {
  164.             $dattr->[$v] = PRIVATE | INHERITED;
  165.         }
  166.         else {
  167.             $dattr->[$v] = INHERITED | $battr->[$v];
  168.             $dfields->{$k} = $v;
  169.         }
  170.     }
  171.  
  172.     foreach my $idx (1..$#{$battr}) {
  173.         next if defined $dattr->[$idx];
  174.         $dattr->[$idx] = $battr->[$idx] & INHERITED;
  175.     }
  176. }
  177.  
  178. 1;
  179.  
  180. __END__
  181.  
  182.