summaryrefslogtreecommitdiff
path: root/pod
diff options
context:
space:
mode:
Diffstat (limited to 'pod')
-rw-r--r--pod/perldiag.pod24
-rw-r--r--pod/perlfunc.pod64
-rw-r--r--pod/perlguts.pod4
-rw-r--r--pod/perlvar.pod65
4 files changed, 153 insertions, 4 deletions
diff --git a/pod/perldiag.pod b/pod/perldiag.pod
index fbeac66515..acd30568a9 100644
--- a/pod/perldiag.pod
+++ b/pod/perldiag.pod
@@ -2263,6 +2263,18 @@ the C<encoding> pragma, is no longer supported as of Perl 5.26.0.
Setting it to anything other than C<undef> is a fatal error as of Perl
5.28.
+=item ${^HOOK}{%s} may only be a CODE reference or undef
+
+(F) You attempted to assign something other than undef or a CODE ref to
+C<%{^HOOK}>. Hooks may only be CODE refs. See L<perlvar/%{^HOOK}> for
+details.
+
+=item Attempt to set unknown hook '%s' in %{^HOOK}
+
+(F) You attempted to assign something other than undef or a CODE ref to
+C<%{^HOOK}>. Hooks may only be CODE refs. See L<perlvar/%{^HOOK}> for
+details.
+
=item entering effective %s failed
(F) While under the C<use filetest> pragma, switching the real and
@@ -3961,11 +3973,17 @@ can vary from one line to the next.
=item Missing or undefined argument to %s
-(F) You tried to call require or do with no argument or with an undefined
-value as an argument. Require expects either a package name or a
-file-specification as an argument; do expects a filename. See
+(F) You tried to call C<require> or C<do> with no argument or with an
+undefined value as an argument. Require expects either a package name or
+a file-specification as an argument; do expects a filename. See
L<perlfunc/require EXPR> and L<perlfunc/do EXPR>.
+=item Missing or undefined argument to %s via %{^HOOK}{require__before}
+
+(F) A C<%{^HOOK}{require__before}> hook rewrote the name of the file being
+compiled with C<require> or C<do> with an empty string an undefined value
+which is forbidden. See L<perlvar/%{^HOOK}> and L<perlfunc/require EXPR>.
+
=item Missing right brace on \%c{} in regex; marked by S<<-- HERE> in m/%s/
(F) Missing right brace in C<\x{...}>, C<\p{...}>, C<\P{...}>, or C<\N{...}>.
diff --git a/pod/perlfunc.pod b/pod/perlfunc.pod
index 90f07afbe8..5a26941e75 100644
--- a/pod/perlfunc.pod
+++ b/pod/perlfunc.pod
@@ -7064,7 +7064,69 @@ require executes at all.
As of 5.37.7 C<@INC> values of undef will be silently ignored.
-For a yet-more-powerful import facility, see
+The function C<require()> is difficult to wrap properly. Many modules
+consult the stack to find information about their caller, and injecting
+a new stack frame by wrapping C<require()> often breaks things.
+Nevertheless it can be very helpful to have the ability to perform
+actions before and after a C<require>, for instance for trace utilities
+like C<Devel::TraceUse> or to measure time to load and the memory
+consumption of the require graph. Because of the difficulties in safely
+creating a C<require()> wrapper in 5.37.10 we introduced a new mechanism.
+
+As of 5.37.10, prior to any other actions it performs, C<require> will
+check if C<${^HOOK}{require__before}> contains a coderef, and if it does
+it will be called with the filename form of the item being loaded. The hook
+may modify C<$_[0]> to load a different filename, or it may throw a fatal
+exception to cause the require to fail, which will be treated as though the
+required code itself had thrown an exception.
+
+The C<${^HOOK}{require__before}> hook may return a code reference, in
+which case the code reference will be executed (in an eval with the
+filname as a parameter) after the require completes. It will be executed
+regardless of how the compilation completed, and even if the require
+throws a fatal exception. The function may consult C<%INC> to determine
+if the require failed or not. For instance the following code will print
+some diagnostics before and after every C<require> statement. The
+example also includes logic to chain the signal, so that multiple
+signals can cooperate. Well behaved C<${^HOOK}{require__before}>
+handlers should always take this into account.
+
+ {
+ use Scalar::Util qw(reftype);
+ my $old_hook = ${^HOOK}{require__before};
+ local ${^HOOK}{require__before} = sub {
+ my ($name) = @_;
+ my $old_hook_ret;
+ $old_hook_ret = $old_hook->($name) if $old_hook;
+ warn "Requiring: $name\n";
+ return sub {
+ $old_hook_ret->() if ref($old_hook_ret)
+ && reftype($old_hook_ret) eq "CODE";
+ warn sprintf "Finished requiring %s: %s\n",
+ $name, $INC{$name} ? "loaded" :"failed";
+ };
+ };
+ require Whatever;
+ }
+
+This hook executes for ALL C<require> statements, unlike C<INC> and
+C<INCDIR> hooks, which are only executed for relative file names, and it
+executes first before any other special behaviour inside of require.
+Note that the initial hook in C<${^HOOK}{require__before}> is *not*
+executed inside of an eval, and throwing an exception will stop further
+processing, but the after hook it may return is executed inside of an
+eval, and any exceptions it throws will be silently ignored. This is
+because it executes inside of the scope cleanup logic that is triggered
+after the require completes, and an exception at this time would not
+stop the module from being loaded, etc.
+
+There is a similar hook that fires after require completes,
+C<${^HOOK}{require__after}>, which will be called after each require statement
+completes, either via an exception or successfully. It will be called with
+the filename of the most recently executed require statement. It is executed
+in an eval, and will not in any way affect execution.
+
+For a yet-more-powerful import facility built around C<require>, see
L<C<use>|/use Module VERSION LIST> and L<perlmod>.
=item reset EXPR
diff --git a/pod/perlguts.pod b/pod/perlguts.pod
index 9f35597d7a..e0101d33ad 100644
--- a/pod/perlguts.pod
+++ b/pod/perlguts.pod
@@ -1555,6 +1555,8 @@ will be lost.
y PERL_MAGIC_defelem vtbl_defelem Shadow "foreach" iterator
variable / smart parameter
vivification
+ Z PERL_MAGIC_hook vtbl_hook %{^HOOK} hash
+ z PERL_MAGIC_hookelem vtbl_hookelem %{^HOOK} hash element
\ PERL_MAGIC_lvref vtbl_lvref Lvalue reference
constructor
] PERL_MAGIC_checkcall vtbl_checkcall Inlining/mutation of call
@@ -1584,6 +1586,8 @@ will be lost.
=for apidoc_item ||PERL_MAGIC_fm
=for apidoc_item ||PERL_MAGIC_hints
=for apidoc_item ||PERL_MAGIC_hintselem
+=for apidoc_item ||PERL_MAGIC_hook
+=for apidoc_item ||PERL_MAGIC_hookelem
=for apidoc_item ||PERL_MAGIC_isa
=for apidoc_item ||PERL_MAGIC_isaelem
=for apidoc_item ||PERL_MAGIC_lvref
diff --git a/pod/perlvar.pod b/pod/perlvar.pod
index aebd6a45bd..25dbd05a9b 100644
--- a/pod/perlvar.pod
+++ b/pod/perlvar.pod
@@ -779,6 +779,71 @@ and use an C<END{}> or CORE::GLOBAL::die override instead.
See L<perlfunc/die>, L<perlfunc/warn>, L<perlfunc/eval>, and
L<warnings> for additional information.
+=item %{^HOOK}
+X<%{^HOOK}>
+
+This hash contains coderefs which are called when various perl keywords
+which are hard or impossible to wrap are called. The keys of this hash
+are named after the keyword that is being hooked, followed by two
+underbars and then a phase term; either "before" or "after".
+
+Perl will throw an error if you attempt modify a key which is not
+documented to exist, or if you attempt to store anything other than a
+code reference or undef in the hash. If you wish to use an object to
+implement a hook you can use currying to embed the object into an
+anonymous code reference.
+
+Currently there is only one keyword which can be hooked, C<require>, but
+it is expected that in future releases there will be additional keywords
+with hook support.
+
+=over 4
+
+=item require__before
+
+The routine indicated by C<${^HOOK}{require__before}> is called by
+C<require> B<before> it checks C<%INC>, looks up C<@INC>, calls INC
+hooks, or compiles any code. It is called with a single argument, the
+filename for the item being required (package names are converted to
+paths). It may alter this filename to change what file is loaded. If
+the hook dies during execution then it will block the require from executing.
+
+In order to make it easy to perform an action with shared state both
+before and after the require keyword was executed the C<require__before>
+hook may return a "post-action" coderef which will in turn be executed when
+the C<require> completes. This coderef will be executed regardless as to
+whether the require completed succesfully or threw an exception. It will
+be called with the filename that was required. You can check %INC to
+determine if the require was successful. Any other return from the
+C<require__before> hook will be silently ignored.
+
+C<require__before> hooks are called in FIFO order, and if the hook
+returns a code reference those code references will be called in FILO
+order. In other words if A requires B requires C, then
+C<require__before> will be called first for A, then B and then C, and
+the post-action code reference will executed first for C, then B and
+then finally A.
+
+Well behaved code should ensure that when setting up a
+C<require__before> hook that any prior installed hook will be called,
+and that their return value, if a code reference, will be called as
+well. See L<perlfunc/require> for an example implementation.
+
+=item require__after
+
+The routine indicated by C<${^HOOK}{require__after}> is called by
+C<require> B<after> the require completes. It is called with a single
+argument, the filename for the item being required (package names are
+converted to paths). It is executed when the C<require> completes,
+either via exception or via completion of the require statement, and you
+can check C<%INC> to determine if the require was successful.
+
+The C<require__after> hook is called for each required file in FILO
+order. In other words if A requires B requires C, then C<require__after>
+will be called first for C, then B and then A.
+
+=back
+
=item $BASETIME
=item $^T