Cant locate multiple methods from Apache2::RequestRec - perl

I'm getting multiple errors from Apache2::RequestRec apache, here they are:
Can't locate object method "args" via package "Apache2::RequestRec" at /usr/lib/perl5/Apache2/Status.pm line 112.
OR
Can't locate object method "uri" via package "Apache2::RequestRec" at /usr/lib/perl5/ModPerl/RegistryCooker.pm line 123.
I'm using mod_perl this way:
LoadModule perl_module /usr/lib/apache2/modules/mod_perl.so
Any suggestions please?

Does your code do:
use Apache2::RequestRec;
The mod_perl2 API is split into multiple modules. This has the advantage that you can chose to load only the parts you need and save on memory. It has the disadvantage that you have to load all the parts you need :-)
See also ModPerl::MethodLookup

Related

How to load module not in INC in Perl during runtime?

How do I load a module with a path not in the #INC in Perl?
I've read the answers on how to add a path to the #INC, but the issue is that #INC has to be changed at the beginning of the code. After it's compiled, all the modules I've come across look to #INC to find the location of the module. My issue is that we're trying to separate out all these environment specific things to a config file. If it's in a config file, the path needs to be read before it can be pushed to #INC, but then the code has already been compiled and it seems #INC can't be modified.
Is there a way? Is there a library that lets me load a module and pass it a custom path?
Is this a terrible bad thing to do? Why?
Perl has an incremental compilation model which means that code can be executed before other code is even parsed. For this, we can use phase blocks (aka. phasers):
BEGIN {
print "This is executed as soon as the block has been parsed\n";
}
Such a phase block could also be used to load a configuration file.
For example, use statements are effectively syntactic sugar for a BEGIN block.
use Foo::Bar qw/baz qux/;
is equivalent to
BEGIN {
require Foo::Bar; # or: require "Foo/Bar.pm";
Foo::Bar->import(qw/baz qux/);
}
We can also load modules at runtime, although that's only sensible for object-oriented modules.
So we have three options:
Load config in the BEGIN phase and add the correct library paths before loading the actual modules
Load the modules manually during BEGIN with their full path (e.g. require "/my/modules/Foo/Bar.pm"
Figure out the configuration at runtime, load modules after that.
Using bare require is fairly uncomfortable, which is why Module::Runtime exists
Use a BEGIN block to load your custom #INC location and then use lib to include it.
# use lib /a special directory/
BEGIN {
my $lib_to_include = ...;
require lib;
lib->import($lib_to_include);
}
use Module_That_Requires_Special_Dir;
The only thing to note is that whatever code you use to load your custom include directory will have to rely on methods already defined before this BEGIN block. Therefore you can't use a subroutine that is later in the file.
Came across only, which seems to let a path be passed to the use argument like so:
use only { versionlib => '/home/ingy/modules' },
MyModule => 0.33;
It has to be used with a version condition, but putting this here anyways since it's relevant to my question 1 and I wasn't able to find any modules first time around that allowed a path outside #INC.
require supposedly is able to take in a full path, according to the perlfaq with
require "$ENV{HOME}/lib/Foo.pm"; # no #INC searching!

Using use without package - big mess?

I have been USEing .pm files willy-nilly in my programs without really getting into using packages unless really needed. In essence, I would just have common routines in a .pm and they would become part of main when use'd (the .pm would have no package or Exporter or the like... just a bunch of routines).
However, I came across a situation the other day which I think I know what happened and why, but I was hoping to get some coaching from the experts here on best practices and how to resolve this. In essence, should packages be used always? Should I "do" files when I just want common routines absorbed into main (or the parent module/package)? Is Exporter really the way to handle all of this?
Here's example code of what I came across (I won't post the original code as it's thousands of lines... this is just the essence of the problem).
Pgm1.pl:
use PM1;
use PM2;
print "main\n";
&pm2sub1;
&pm1sub1;
PM1.pm:
package PM1;
require Exporter;
#ISA=qw(Exporter);
#EXPORT=qw(pm1sub1);
use Data::Dump 'dump';
use PM2;
&pm2sub1;
sub pm1sub1 {
print "pm1sub1 from caller ",dump(caller()),"\n";
&pm2sub1;
}
1;
PM2.pm:
use Data::Dump 'dump';
sub pm2sub1 {
print "pm2sub1 from caller ",dump(caller()),"\n";
}
1;
In essence, I'd been use'ing PM2.pm for some time with its &pm2sub1 subroutine. Then I wrote PM1.pm at some point and it needed PM2.pm's routines as well. However, in doing it like this, PM2.pm's modules got absorbed into PM2.pm's package and then Pgm1.pl couldn't do the same since PM2.pm had already been use'd.
This code will produce
Undefined subroutine &main::pm2sub1 called at E:\Scripts\PackageFun\Pgm1.pl line 4.
pm2sub1 from caller ("PM1", "PM1.pm", 7)
main
However, when I swap the use statements like so in Pgm1.pl
use PM2;
use PM1;
print "main\n";
&pm2sub1;
&pm1sub1;
... perl will allow PM2.pm's modules into main, but then not into PM1.pm's package:
Undefined subroutine &PM1::pm2sub1 called at PM1.pm line 7.
Compilation failed in require at E:\Scripts\PackageFun\Pgm1.pl line 2.
BEGIN failed--compilation aborted at E:\Scripts\PackageFun\Pgm1.pl line 2.
So, I think I can fix this by getting religious about packages and Exporter in all my modules. Trouble is, PM2.pm is already used in a great number of other programs, so it would be a ton of regression testing to make sure I didn't break anything.
Ideas?
See my answer to What is the difference between library files and modules?.
Only use require (and thus use) for modules (files with package, usually .pm). For "libraries" (files without package, usually .pl), use do.
Better yet, only use modules!
use will not load same file more than once. It will, however, call target package's import sub every time. You should format your PM2 as proper package, so use can find its import and export function to requestor's namespace from there.
(Or you could sneak your import function into proper package by fully qualifying its name, but don't do that.)
You're just asking for trouble arranging your code like this. Give each module a package name (namespace), then fully qualify calls to its functions, e.g. PM2::sub1() to call sub1 in package PM2. You are already naming the functions with the package name on them (pm2sub1); it is two extra characters (::) to do it the right way and then you don't need to bother with Exporter either.

Including files in pm modul

I am totally new to Perl/Fastcgi.
I have some pm-modules to which will have to add a lot of scripts and over time it will grow and grow. Hence, I need a structure which makes the admin easier.
So, I want to create files in some kind of directory structure which I can include. I want the files that I include will be exaclty like if the text were written in the file where I do the include.
I have tried 'do', 'use' and 'require'. The actual file I want to include is in one of the directories Perl is looking in. (verified using perl -V)
I have tried within and outside BEGIN {}.
How do I do this? Is it possible at all including pm files in pm files? Does it have to be pm-files I include or can it be any extension?
I have tried several ways, included below is my last try.
Config.pm
package Kernel::Config;
sub Load {
#other activities
require 'severalnines.pm';
#other activities
}
1;
severalnines.pm
# Filter Queues
$Self->{TicketAcl}->{'ACL-hide-queues'} = {
Properties => {
},
PossibleNot => {Ticket => { Queue =>
['[RegExp]^*'] },
},
};
1;
I'm not getting any errors in the Apache's error_log related to this. Still, the code is not recognized like it would be if I put it in the Config.pm file.
I am not about to start programming a lot, just do some admin in a 3rd party application. Still, I have searched around trying to learn how it works with including files. Is the severalnines.pm considered to be a perl module and do I need to use a program like h2xs, or similar, in order to "create" the module (told you, totally newbie...)?
Thanks in advance!
I usually create my own module prefix -- named after the project or the place I worked. For example, you might put everything under Mu with modules named like Mu::Foo and Mu::Bar. Use multiple modules (don't try to keep everything in one single file) and name your modules with the *.pm suffix.
Then, if the Mu directory is in the same directory as your programs, you only need to do this:
use Mu::Foo;
use Mu::Bar;
If they're in another directory, you can do this:
use lib qw(/path/to/other/directory);
use Mu::Foo;
use Mu::Bar;
Is it possible at all including pm files in pm files?
Why certainly yes.
So, I want to create files in some kind of directory structure which I can include. I want the files that I include will be exaclty like if the text were written in the file where I do the include.
That's a bad, bad idea. You are better off using the package mechanism. That is, declare each of your module as a separate package name. Otherwise, your module will have a variable or function in it that your script will override, and you'll never, ever know it.
In Perl, you can reference variables in your modules by prefixing it with the module name. (Such as File::Find does. For example $File::Find::Name is the found file's name. This doesn't pollute your namespace.
If you really want your module's functions and variables in your namespace, look at the #EXPORT_OK list variable in Exporter. This is a list of all the variables and functions that you'd like to import into your module's namespace. However, it's not automatic, you have to list them next to your use statement. That way, you're more likely to know about them. Using Exporter isn't too difficult. In your module, you'd put:
package Mu::Foo;
use Exporter qw(import);
our EXPORT_OK = qw(convert $fundge #ribitz);
Then, in your program, you'd put:
use Mu::Foo qw(convert $fundge #ribitz);
Now you can access convert, $fundge and #ribitz as if they were part of your main program. However, you now have documented that you're pulling in these subroutines and variables from Mu::Foo.
(If you think this is complex, be glad I didn't tell you that you really should use Object Oriented methods in your Modules. That's really the best way to do it.)
if ( 'I want the files that I include will be exactly like if the text were written in the file where I do the include.'
&& 'have to add a lot of scripts and over time it will grow and grow') {
warn 'This is probably a bad idea because you are not creating any kind of abstraction!';
}
Take a look at Exporter, it will probably give you a good solution!

How do I find all the modules used by a Perl script?

I'm getting ready to try to deploy some code to multiple machines. As far as I know, using a Makefile.pm to track dependencies is the best way to ensure they are installed everywhere. The problem I have is I'm not sure our Makefile.pm has been updated as this application has passed through a few different developers.
Is there any way to automatically parse through either my source or a few full runs of my program to determine exactly what versions of what modules my application is depending on? On top of that, is there any way to filter it based on CPAN packages? (So that I only depend on Moose instead of every single module that comes with Moose.)
A third related question is, if you depend on a version of a module that is not the latest, what is the best way to have someone else install it? Should I start including entire localized Perl installations with my application?
Just to be clear - you can not generically get a list of modules that the app depends on by code analysis alone. E.g. if your apps does eval { require $module; $module->import() }, where $module is passed via command line, then this can ONLY be detected by actually running the specific command line version with ALL the module values.
If you do wish to do this, you can figure out every module used by a combination of runs via:
Devel::Cover. Coverage reports would list 100% of modules used. But you don't get version #s.
Print %INC at every single possible exit point in the code as slu's answer said. This should probably be done in END{} block as well as __DIE__ handler to cover all possible exit points, and even then may be not fully 100% covering in generic case if somewhere within the program your __DIE__ handler gets overwritten.
Devel::Modlist (also mentioned by slu's answer) - the downside compared to Devel::Cover is that it does NOT seem to be able to aggregate a database across multiple sample runs like Devel::Cover does. On the plus side, it's purpose-built, so has a lot of very useful options (CPAN paths, versions).
Please note that the other module (Module::ScanDeps) does NOT seem to allow you to do runtime analysis based on arbitrary command line arguments (e.g. it seems at first glance to only allow you to execute the program with no arguments) and if that's true, is inferior to all the above 3 methods for any code that may possibly load modules dynamically.
Module::ScanDeps - Recursively scan Perl code for dependencies
Does both static and runtime scanning. Just modules, I don't know of any exact way of verifying what versions from what distributions. You could get old packages from BackPan, or just package your entire chain of local dependencies up with PAR.
You could look at %INC, see http://www.perlmonks.org/?node_id=681911 which also mentions Devel::Modlist
I would definitely use Devel::TraceUse, which also shows a tree of the modules, so it's easy to guess where they are being loaded.

Can I make a single Perl module act as multiple kinds of mod_perl handlers?

I'm writing a series of related mod_perl handlers for various login-related functions in Apache, so my Apache config file looks like this (for example)
PerlAccessHandler MyApache::MyAccess
PerlAuthenHandler MyApache::MyAuthen
PerlAuthzHandler MyApache::MyAuthz
Each of the modules (MyAccess, MyAuthen, MyAuthz) defines a
sub handler() {}
Which mod_perl calls at the relevant point in the processing of the request.
What I'd like to know is whether there is a way of doing this with one Perl module rather than three (it's just tidier and less work for users to install one module instead of 3)?
Is there some way to define the name of the handler method, perhaps. Or is there a way of detecting from within the handler() code which sort of handling I'm supposed to be doing?
It appears from the mod_perl 2.0 docs that you can use the "method" syntax to do what you're wanting (I've not tested this):
PerlAccessHandler MyApache::MyLoginModule->access_handler
PerlAuthenHandler MyApache::MyLoginModule->authen_handler
PerlAuthzHandler MyApache::MyLoginModule->authz_handler
I believe this will cause mod_perl to call each of the named methods in a static way on your MyApache::MyLoginModule class.
You can also create an object to be used when calling a handler method if you want to:
<Perl>
use MyApache::MyLoginModule;
$MyApache::MyLoginModule::access = MyApache::MyLoginModule->new(phase => 'access');
$MyApache::MyLoginModule::authen = MyApache::MyLoginModule->new(phase => 'authen');
$MyApache::MyLoginModule::authz = MyApache::MyLoginModule->new(phase => 'authz');
</Perl>
PerlAccessHandler $MyApache::MyLoginModule::access->handler
PerlAuthenHandler $MyApache::MyLoginModule::authen->handler
PerlAuthzHandler $MyApache::MyLoginModule::authz->handler
This approach would allow you to have a single handler method that could have different behavior based on the properties of the object set up upon object creation.
Disclaimer: It's been a while since I've worked with this part of mod_perl configuration so your results may vary!
Looks like one possibility might be using the push_handlers() call and setting up the handlers in code rather than in the apache conf file
See here: http://tinyurl.com/bwdeew