1=head1 NAME 2 3ModPerl::MethodLookup -- Lookup mod_perl modules, objects and methods 4 5=head1 Synopsis 6 7 use ModPerl::MethodLookup; 8 9 # return all module names containing XS method 'print' 10 my ($hint, @modules) = 11 ModPerl::MethodLookup::lookup_method('print'); 12 13 # return only module names containing method 'print' which 14 # expects the first argument to be of type 'Apache2::Filter' 15 # (here $filter is an Apache2::Filter object) 16 my ($hint, @modules) = 17 ModPerl::MethodLookup::lookup_method('print', $filter); 18 # or 19 my ($hint, @modules) = 20 ModPerl::MethodLookup::lookup_method('print', 'Apache2::Filter'); 21 22 # what XS methods defined by module 'Apache2::Filter' 23 my ($hint, @methods) = 24 ModPerl::MethodLookup::lookup_module('Apache2::Filter'); 25 26 # what XS methods can be invoked on the object $r (or a ref) 27 my ($hint, @methods) = 28 ModPerl::MethodLookup::lookup_object($r); 29 # or 30 my ($hint, @methods) = 31 ModPerl::MethodLookup::lookup_object('Apache2::RequestRec'); 32 33 # preload all mp2 modules in startup.pl 34 ModPerl::MethodLookup::preload_all_modules(); 35 36 # command line shortcuts 37 % perl -MModPerl::MethodLookup -e print_module \ 38 Apache2::RequestRec Apache2::Filter 39 % perl -MModPerl::MethodLookup -e print_object Apache2 40 % perl -MModPerl::MethodLookup -e print_method \ 41 get_server_built request 42 % perl -MModPerl::MethodLookup -e print_method read 43 % perl -MModPerl::MethodLookup -e print_method read APR::Bucket 44 45 46 47 48=head1 Description 49 50mod_perl 2.0 provides many methods, which reside in various 51modules. One has to load each of the modules before using the desired 52methods. C<ModPerl::MethodLookup> provides the Perl API for finding 53module names which contain methods in question and other helper 54functions, to find out out what methods defined by some module, what 55methods can be called on a given object, etc. 56 57 58 59 60=head1 API 61 62 63 64 65=head2 C<lookup_method()> 66 67Find modules (packages) containing a certain method 68 69 ($hint, @modules) = lookup_method($method_name); 70 ($hint, @modules) = lookup_method($method_name, $object); 71 ($hint, @modules) = lookup_method($method_name, $class)); 72 73=over 4 74 75=item arg1: C<$method_name> ( string ) 76 77the method name to look up 78 79=item opt arg2: C<$object> or C<$class> 80 81a blessed object or the name of the class it's blessed into. If there 82is more than one match, this extra information is used to return only 83modules containing methods operating on the objects of the same kind. 84 85If a sub-classed object is passed it'll be handled correctly, by 86checking its super-class(es). This usage is useful when the 87C<L<AUTOLOAD|/C_AUTOLOAD_>> is used to find a not yet loaded module 88which include the called method. 89 90=item ret1: C<$hint> 91 92a string containing a human readable lookup result, suggesting which 93modules should be loaded, ready for copy-n-paste or explaining the 94failure if the lookup didn't succeed. 95 96=item ret2: C<@modules> 97 98an array of modules which have matched the query, i.e. the names of 99the modules which contain the requested method. 100 101=item since: 2.0.00 102 103=back 104 105Examples: 106 107Return all module names containing XS method I<print>: 108 109 my ($hint, @modules) = 110 ModPerl::MethodLookup::lookup_method('print'); 111 112Return only module names containing method I<print> which expects the 113first argument to be of type C<Apache2::Filter>: 114 115 my $filter = bless {}, 'Apache2::Filter'; 116 my ($hint, @modules) = 117 ModPerl::MethodLookup::lookup_method('print', $filter); 118 119or: 120 121 my ($hint, @modules) = 122 ModPerl::MethodLookup::lookup_method('print', 'Apache2::Filter'); 123 124 125 126 127 128 129 130 131=head2 C<lookup_module()> 132 133Find methods contained in a certain module (package) 134 135 ($hint, @methods) = lookup_module($module_name); 136 137=over 4 138 139=item arg1: C<$module_name> ( string ) 140 141the module name 142 143=item ret1: C<$hint> 144 145a string containing a human readable lookup result, suggesting, which 146methods the module C<$module_name> implements, or explaining the 147failure if the lookup failed. 148 149=item ret2: C<@methods> 150 151an array of methods which have matched the query, i.e. the names of 152the methods defined in the requested module. 153 154=item since: 2.0.00 155 156=back 157 158Example: 159 160What XS methods defined by module C<Apache2::Filter>: 161 162 my ($hint, @methods) = 163 ModPerl::MethodLookup::lookup_module('Apache2::Filter'); 164 165 166 167 168 169 170 171=head2 C<lookup_object()> 172 173 ($hint, @methods) = lookup_object($object); 174 ($hint, @methods) = lookup_object($class); 175 176=over 4 177 178=item arg1: C<$object> or C<$class> 179 180an object or a name of a class an object is blessed into 181 182If a sub-classed object is passed it'll be handled correctly, by 183including methods provided by its super-class(es). 184 185=item ret1: C<$hint> 186 187a string containing a human readable lookup result, suggesting, which 188methods the given object can invoke (including module names that need 189to be loaded to use those methods), or explaining the failure if the 190lookup failed. 191 192=item ret2: C<@methods> 193 194an array of methods which have matched the query, i.e. the names of 195the methods that can be invoked on the given object (or its class 196name). 197 198=item since: 2.0.00 199 200=back 201 202META: As of this writing this function may miss some of the 203functions/methods that can be invoked on the given object. Currently 204we can't programmatically deduct the objects they are invoked on, 205because these methods are written in pure XS and manipulate the 206arguments stack themselves. Currently these are mainly XS functions, 207not methods, which of course aren't invoked on objects. There are also 208logging function wrappers (C<Apache2::Log>). 209 210Examples: 211 212What XS methods can be invoked on the object C<$r>: 213 214 my ($hint, @methods) = 215 ModPerl::MethodLookup::lookup_object($r); 216 217or C<$r>'s class -- C<Apache2::RequestRec>: 218 219 my ($hint, @methods) = 220 ModPerl::MethodLookup::lookup_object('Apache2::RequestRec'); 221 222 223 224 225 226=head2 C<preload_all_modules()> 227 228The function C<preload_all_modules()> preloads all mod_perl 2.0 229modules, which implement their API in XS. This is similar to the 230mod_perl 1.0 behavior which has most of its methods loaded at the 231startup. 232 233CPAN modules developers should make sure their distribution loads each 234of the used mod_perl 2.0 modules explicitly, and not use this 235function, as it takes the fine control away from the users. One should 236avoid doing this the production server (unless all modules are used 237indeed) in order to save memory. 238 239=over 240 241=item since: 2.0.00 242 243=back 244 245 246 247 248 249 250 251=head2 C<print_method()> 252 253C<print_method()> is a convenience wrapper for 254C<L<lookup_method()|/C_lookup_method___>>, mainly designed to be used 255from the command line. For example to print all the modules which 256define method I<read> execute: 257 258 % perl -MModPerl::MethodLookup -e print_method read 259 260Since this will return more than one module, we can narrow the query 261to only those methods which expect the first argument to be blessed 262into class C<APR::Bucket>: 263 264 % perl -MModPerl::MethodLookup -e print_method read APR::Bucket 265 266You can pass more than one method and it'll perform a lookup on each 267of the methods. For example to lookup methods C<get_server_built> and 268C<request> you can do: 269 270 % perl -MModPerl::MethodLookup -e print_method \ 271 get_server_built request 272 273The function C<print_method()> is exported by default. 274 275=over 276 277=item since: 2.0.00 278 279=back 280 281 282 283 284=head2 C<print_module()> 285 286C<print_module()> is a convenience wrapper for 287C<L<lookup_module()|/C_lookup_module___>>, mainly designed to be used 288from the command line. For example to print all the methods defined in 289the module C<Apache2::RequestRec>, followed by methods defined in the 290module C<Apache2::Filter> you can run: 291 292 % perl -MModPerl::MethodLookup -e print_module \ 293 Apache2::RequestRec Apache2::Filter 294 295The function C<print_module()> is exported by default. 296 297=over 298 299=item since: 2.0.00 300 301=back 302 303 304 305 306 307=head2 C<print_object()> 308 309C<print_object()> is a convenience wrapper for 310C<L<lookup_object()|/C_lookup_object___>>, mainly designed to be used 311from the command line. For example to print all the methods that can 312be invoked on object blessed into a class C<Apache2::RequestRec> run: 313 314 % perl -MModPerl::MethodLookup -e print_object \ 315 Apache2::RequestRec 316 317Similar to C<L<print_object()|/C_print_object___>>, more than one 318class can be passed to this function. 319 320The function C<print_object()> is exported by default. 321 322=over 323 324=item since: 2.0.00 325 326=back 327 328 329 330 331 332 333 334=head1 Applications 335 336 337 338 339 340=head2 C<AUTOLOAD> 341 342When Perl fails to locate a method it checks whether the package the 343object belongs to has an C<AUTOLOAD> function defined and if so, calls 344it with the same arguments as the missing method while setting a 345global variable C<$AUTOLOAD> (in that package) to the name of the 346originally called method. We can use this facility to lookup the 347modules to be loaded when such a failure occurs. Though since we have 348many packages to take care of we will use a special 349C<UNIVERSAL::AUTOLOAD> function which Perl calls if can't find the 350C<AUTOLOAD> function in the given package. 351 352In that function you can query C<ModPerl::MethodLookup>, require() the 353module that includes the called method and call that method again 354using the goto() trick: 355 356 use ModPerl::MethodLookup; 357 sub UNIVERSAL::AUTOLOAD { 358 my ($hint, @modules) = 359 ModPerl::MethodLookup::lookup_method($UNIVERSAL::AUTOLOAD, @_); 360 if (@modules) { 361 eval "require $_" for @modules; 362 goto &$UNIVERSAL::AUTOLOAD; 363 } 364 else { 365 die $hint; 366 } 367 } 368 369However we don't endorse this approach. It's a better approach to 370always abort the execution which printing the C<$hint>and use fix the 371code to load the missing module. Moreover installing 372C<UNIVERSAL::AUTOLOAD> may cause a lot of problems, since once it's 373installed Perl will call it every time some method is missing 374(e.g. undefined C<DESTROY> methods). The following approach seems to 375somewhat work for me. It installs C<UNIVERSAL::AUTOLOAD> only when the 376the child process starts. 377 378 httpd.conf: 379 ----------- 380 PerlChildInitHandler ModPerl::MethodLookupAuto 381 382 startup.pl: 383 ----------- 384 { 385 package ModPerl::MethodLookupAuto; 386 use ModPerl::MethodLookup; 387 388 use Carp; 389 sub handler { 390 391 *UNIVERSAL::AUTOLOAD = sub { 392 my $method = $AUTOLOAD; 393 return if $method =~ /DESTROY/; # exclude DESTROY resolving 394 395 my ($hint, @modules) = 396 ModPerl::MethodLookup::lookup_method($method, @_); 397 $hint ||= "Can't find method $AUTOLOAD"; 398 croak $hint; 399 }; 400 return 0; 401 } 402 } 403 404This example doesn't load the modules for you. It'll print to STDERR 405what module should be loaded, when a method from the not-yet-loaded 406module is called. 407 408A similar technique is used by 409C<L<Apache2::porting|docs::2.0::api::Apache2::porting>>. 410 411 412META: there is a better version of AUTOLOAD discussed on the dev 413list. Replace the current one with it. (search the archive for 414EazyLife) 415 416 417 418 419 420=head2 Command Line Lookups 421 422When a method is used and mod_perl has reported a failure to find it, 423it's often useful to use the command line query to figure out which 424module needs to be loaded. For example if when executing: 425 426 $r->construct_url(); 427 428mod_perl complains: 429 430 Can't locate object method "construct_url" via package 431 "Apache2::RequestRec" at ... 432 433you can ask C<ModPerl::MethodLookup> for help: 434 435 % perl -MModPerl::MethodLookup -e print_method construct_url 436 To use method 'construct_url' add: 437 use Apache2::URI (); 438 439and after copy-n-pasting the use statement in our code, the problem 440goes away. 441 442One can create a handy alias for this technique. For example, C-style 443shell users can do: 444 445 % alias lookup "perl -MModPerl::MethodLookup -e print_method" 446 447For Bash-style shell users: 448 449 % alias lookup="perl -MModPerl::MethodLookup -e print_method" 450 451Now the lookup is even easier: 452 453 % lookup construct_url 454 to use method 'construct_url' add: 455 use Apache2::URI; 456 457Similar aliases can be provided for 458C<L<print_object()|/C_print_object___>> and 459C<L<print_module()|/C_print_module___>>. 460 461 462 463 464 465=head1 Todo 466 467These methods aren't yet picked by this module (the extract from the 468map file): 469 470 modperl_filter_attributes | MODIFY_CODE_ATTRIBUTES 471 modperl_spawn_proc_prog | spawn_proc_prog 472 apr_ipsubnet_create | new 473 474Please report to L<the mod_perl development mailing 475list|maillist::dev> if you find any other missing methods. But remember that 476as of this moment the module reports only XS functions. In the future 477we may add support for pure perl functions/methods as well. 478 479 480 481 482 483 484 485 486=head1 See Also 487 488=over 489 490=item * 491 492L<the mod_perl 1.0 backward compatibility 493document|docs::2.0::user::porting::compat/> 494 495=item * 496 497L<porting Perl modules|docs::2.0::user::porting::porting> 498 499=item * 500 501L<porting XS modules|docs::2.0::devel::porting::porting> 502 503=item * 504 505C<L<Apache2::porting|docs::2.0::api::Apache2::porting>> 506 507=back 508 509 510 511 512 513=head1 Copyright 514 515mod_perl 2.0 and its core modules are copyrighted under 516The Apache Software License, Version 2.0. 517 518 519 520 521=head1 Authors 522 523L<The mod_perl development team and numerous 524contributors|about::contributors::people>. 525 526=cut 527