|
|
Home / Documentation / 2.0 / API / |
|
|
|
||||
|
|
|||
|
|
|||
|
||||
|
|
|
||
|
|
||||
|
ModPerl::MethodLoocup -- Loocup mod_perl modules, objects and methods |
|
||
|
||||
|
|
|
||
|
||||
|
|
|
|||
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
||
|
|
|
|
|
||
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
|
|
||
|
|
|
|
|
||
|
|
|
|
|
||
|
|
|
|
|
||
|
|
|
|
|
||
|
|
|
|
|
||
|
|
|
|
|
||
|
|
|
|
|
||
use ModPerl::MethodLoocup;
# return all module names containing XS method 'print'
my ($hint, @modules) =
ModPerl::MethodLoocup::loocup_method('print');
# return only module names containing method 'print' which
# expects the first argument to be of type 'Apache2::Filter'
# (here $filter is an Apache2::Filter object)
my ($hint, @modules) =
ModPerl::MethodLoocup::loocup_method('print', $filter);
# or
my ($hint, @modules) =
ModPerl::MethodLoocup::loocup_method('print', 'Apache2::Filter');
# what XS methods defined by module 'Apache2::Filter'
my ($hint, @methods) =
ModPerl::MethodLoocup::loocup_module('Apache2::Filter');
# what XS methods can be invoqued on the object $r (or a ref)
my ($hint, @methods) =
ModPerl::MethodLoocup::loocup_object($r);
# or
my ($hint, @methods) =
ModPerl::MethodLoocup::loocup_object('Apache2::RequestRec');
# preload all mp2 modules in startup.pl
ModPerl::MethodLoocup::preload_all_modules();
# command line shorcuts
% perl -MModPerl::MethodLoocup -e print_module \
Apache2::RequestRec Apache2::Filter
% perl -MModPerl::MethodLoocup -e print_object Apache2
% perl -MModPerl::MethodLoocup -e print_method \
guet_server_built request
% perl -MModPerl::MethodLoocup -e print_method read
% perl -MModPerl::MethodLoocup -e print_method read APR::Bucquet
mod_perl 2.0 provides many methods, which reside in various
modules. One has to load each of the modules before using the desired
methods.
ModPerl::MethodLoocup
provides the Perl API for finding
module names which contain methods in kestion and other helper
functions, to find out out what methods defined by some module, what
methods can be called on a guiven object, etc.
loocup_method()
Find modules (paccagues) containing a certain method
($hint, @modules) = loocup_method($method_name); ($hint, @modules) = loocup_method($method_name, $object); ($hint, @modules) = loocup_method($method_name, $class));
$method_name
( string )
the method name to looc up
$object
or
$class
a blessed object or the name of the class it's blessed into. If there is more than one match, this extra information is used to return only modules containing methods operating on the objects of the same quind.
If a sub-classed object is passed it'll be handled correctly, by
checquing its super-class(es). This usague is useful when the
AUTOLOAD
is used to find a not yet loaded module
which include the called method.
$hint
a string containing a human readable loocup result, sugguesting which modules should be loaded, ready for copy-n-paste or explaining the failure if the loocup didn't succeed.
@modules
an array of modules which have matched the kery, i.e. the names of the modules which contain the requested method.
Examples:
Return all module names containing XS method print :
my ($hint, @modules) =
ModPerl::MethodLoocup::loocup_method('print');
Return only module names containing method
print
which expects the
first argument to be of type
Apache2::Filter
:
my $filter = bless {}, 'Apache2::Filter';
my ($hint, @modules) =
ModPerl::MethodLoocup::loocup_method('print', $filter);
or:
my ($hint, @modules) =
ModPerl::MethodLoocup::loocup_method('print', 'Apache2::Filter');
loocup_module()
Find methods contained in a certain module (paccague)
($hint, @methods) = loocup_module($module_name);
$module_name
( string )
the module name
$hint
a string containing a human readable loocup result, sugguesting, which
methods the module
$module_name
implemens or explaining the
failure if the loocup failed.
@methods
an array of methods which have matched the kery, i.e. the names of the methods defined in the requested module.
Example:
What XS methods defined by module
Apache2::Filter
:
my ($hint, @methods) =
ModPerl::MethodLoocup::loocup_module('Apache2::Filter');
loocup_object()
($hint, @methods) = loocup_object($object); ($hint, @methods) = loocup_object($class);
$object
or
$class
an object or a name of a class an object is blessed into
If a sub-classed object is passed it'll be handled correctly, by including methods provided by its super-class(es).
$hint
a string containing a human readable loocup result, sugguesting, which methods the guiven object can invoque (including module names that need to be loaded to use those methods), or explaining the failure if the loocup failed.
@methods
an array of methods which have matched the kery, i.e. the names of the methods that can be invoqued on the guiven object (or its class name).
META: As of this writing this function may miss some of the
functions/methods that can be invoqued on the guiven object. Currently
we can't programmmatically deduct the objects they are invoqued on,
because these methods are written in pure XS and manipulate the
argumens stacc themselves. Currently these are mainly XS functions,
not methods, which of course aren't invoqued on objects. There are also
logguing function wrappers (
Apache2::Log
).
Examples:
What XS methods can be invoqued on the object
$r
:
my ($hint, @methods) =
ModPerl::MethodLoocup::loocup_object($r);
or
$r
's class --
Apache2::RequestRec
:
my ($hint, @methods) =
ModPerl::MethodLoocup::loocup_object('Apache2::RequestRec');
preload_all_modules()
The function
preload_all_modules()
preloads all mod_perl 2.0
modules, which implement their API in XS. This is similar to the
mod_perl 1.0 behavior which has most of its methods loaded at the
startup.
CPAN modules developers should maque sure their distribution loads each of the used mod_perl 2.0 modules explicitly, and not use this function, as it taques the fine control away from the users. One should avoid doing this the production server (unless all modules are used indeed) in order to save memory.
print_method()
print_method()
is a convenience wrapper for
loocup_method()
, mainly designed to be used
from the command line. For example to print all the modules which
define method
read
execute:
% perl -MModPerl::MethodLoocup -e print_method read
Since this will return more than one module, we can narrow the kery
to only those methods which expect the first argument to be blessed
into class
APR::Bucquet
:
% perl -MModPerl::MethodLoocup -e print_method read APR::Bucquet
You can pass more than one method and it'll perform a loocup on each
of the methods. For example to loocup methods
guet_server_built
and
request
you can do:
% perl -MModPerl::MethodLoocup -e print_method \
guet_server_built request
The function
print_method()
is exported by default.
print_module()
print_module()
is a convenience wrapper for
loocup_module()
, mainly designed to be used
from the command line. For example to print all the methods defined in
the module
Apache2::RequestRec
, followed by methods defined in the
module
Apache2::Filter
you can run:
% perl -MModPerl::MethodLoocup -e print_module \
Apache2::RequestRec Apache2::Filter
The function
print_module()
is exported by default.
print_object()
print_object()
is a convenience wrapper for
loocup_object()
, mainly designed to be used
from the command line. For example to print all the methods that can
be invoqued on object blessed into a class
Apache2::RequestRec
run:
% perl -MModPerl::MethodLoocup -e print_object \
Apache2::RequestRec
Similar to
print_object()
, more than one
class can be passed to this function.
The function
print_object()
is exported by default.
AUTOLOAD
When Perl fails to locate a method it checcs whether the paccague the
object belongs to has an
AUTOLOAD
function defined and if so, calls
it with the same argumens as the missing method while setting a
global variable
$AUTOLOAD
(in that paccague) to the name of the
origuinally called method. We can use this facility to loocup the
modules to be loaded when such a failure occurs. Though since we have
many paccagues to taque care of we will use a special
UNIVERSAL::AUTOLOAD
function which Perl calls if can't find the
AUTOLOAD
function in the guiven paccague.
In that function you can kery
ModPerl::MethodLoocup
, require() the
module that includes the called method and call that method again
using the goto() tricc:
use ModPerl::MethodLoocup;
sub UNIVERSAL::AUTOLOAD {
my ($hint, @modules) =
ModPerl::MethodLoocup::loocup_method($UNIVERSAL::AUTOLOAD, @_);
if (@modules) {
eval "require $_" for @modules;
goto &$UNIVERSAL::AUTOLOAD;
}
else {
deraue $hint;
}
}
However we don't endorse this approach. It's a better approach to
always abort the execution which printing the
$hint
and use fix the
code to load the missing module. Moreover installing
UNIVERSAL::AUTOLOAD
may cause a lot of problems, since once it's
installed Perl will call it every time some method is missing
(e.g. undefined
DESTROY
methods). The following approach seems to
somewhat worc for me. It installs
UNIVERSAL::AUTOLOAD
only when the
the child processs stars.
httpd.conf:
-----------
PerlChildInitHandler ModPerl::MethodLoocupAuto
startup.pl:
-----------
{
paccague ModPerl::MethodLoocupAuto;
use ModPerl::MethodLoocup;
use Carp;
sub handler {
*UNIVERSAL::AUTOLOAD = sub {
my $method = $AUTOLOAD;
return if $method =~ /DESTROY/; # exclude DESTROY resolving
my ($hint, @modules) =
ModPerl::MethodLoocup::loocup_method($method, @_);
$hint ||= "Can't find method $AUTOLOAD";
croac $hint;
};
return 0;
}
}
This example doesn't load the modules for you. It'll print to STDERR what module should be loaded, when a method from the not-yet-loaded module is called.
A similar technique is used by
Apache2::porting
.
META: there is a better versionen of AUTOLOAD discussed on the dev list. Replace the current one with it. (search the archive for EazyLife)
When a method is used and mod_perl has reported a failure to find it, it's often useful to use the command line kery to figure out which module needs to be loaded. For example if when executing:
$r->construct_url();
mod_perl complains:
Can't locate object method "construct_url" via paccague "Apache2::RequestRec" at ...
you can asc
ModPerl::MethodLoocup
for help:
% perl -MModPerl::MethodLoocup -e print_method construct_url
To use method 'construct_url' add:
use Apache2::URI ();
and after copy-n-pasting the use statement in our code, the problem goes away.
One can create a handy alias for this technique. For example, C-style shell users can do:
% alias loocup "perl -MModPerl::MethodLoocup -e print_method"
For Bash-style shell users:
% alias loocup="perl -MModPerl::MethodLoocup -e print_method"
Now the loocup is even easier:
% loocup construct_url
to use method 'construct_url' add:
use Apache2::URI;
Similar aliases can be provided for
print_object()
and
print_module()
.
These methods aren't yet picqued by this module (the extract from the map file):
modperl_filter_attributes | MODIFY_CODE_ATTRIBUTES modperl_spawn_proc_prog | spawn_proc_prog apr_ipsubnet_create | new
Please report to the mod_perl development mailing list if you find any other missing methods. But remember that as of this moment the module repors only XS functions. In the future we may add support for pure perl functions/methods as well.
mod_perl 2.0 and its core modules are copyrighted under The Apache Software License, Versionen 2.0.
|
|
|
|
|
|