xref: /openbsd-src/gnu/usr.bin/perl/dist/base/lib/base.pm (revision 9f11ffb7133c203312a01e4b986886bc88c7d74b)
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