[Cascavel-pm] mod_perl
kleber
payback em oi.com.br
Domingo Novembro 30 11:33:55 PST 2014
Olá Srs ,
Instalei o mod_perl no meu computador sendo que ao iniciá-lo recebo a
seguinte mensagem :
[Sun Nov 30 09:29:28 2014] [notice] Apache/2.2.22 (Win32) PHP/5.2.8
mod_apreq2-20090110/2.8.0 mod_perl/2.0.7 Perl/v5.16.3 configured -- resuming
normal operations
Utilizei a seguinte configuração no apache :
PerlModule ModPerl::RegistryBB
<Files ~ "\.plx$">
SetHandler perl-script
PerlResponseHandler ModPerl::RegistryBB::handler
PerlOptions +ParseHeaders
Options -Indexes MultiViews FollowSymLinks +ExecCGI
PerlSendHeader On
Order allow,deny
Allow from all
</Files>
Consigo executar vários scripts em mod_perl porém estou tendo problema com
scripts que tem as instruções :
require 'c:\\payback\\dosbox.plx';
grava_conf($conf,$prog);
Quando executo o script com esta característica recebo a seguinte mensagem
de erro :
[error]Undefined subroutine
&ModPerl::ROOT::ModPerl::RegistryBB::C_3a_Payback_Contabil_Operacao_Fluxo_Formulario_2eplx::grava_conf
called at C:/Payback/Formulario.plx line 47.
Nota - Em ambiente cgi ( sem mod_perl ) todos os scripts são executados
normalmente ( sem problemas ).
Pesquisando na internet encontrei o seguinte texto no perl.apache.org : (
http://perl.apache.org/docs/1.0/guide/porting.html - See Names collisions
with Modules and libs.) :
There are three solutions for this:
.Solution 1
The first two faulty scenarios can be solved by placing your library modules
in a subdirectory structure so that they have different path prefixes.
The file system layout will be something like:
./tool1/Tool1/Foo.pm
./tool1/tool1.pl
./tool2/Tool2/Foo.pm
./tool2/tool2.pl
And modify the scripts:
use Tool1::Foo;
use Tool2::Foo;
For require() (scenario number 2) use the following:
./tool1/tool1-lib/config.pl
./tool1/tool1.pl
./tool2/tool2-lib/config.pl
./tool2/tool2.pl
And each script contains respectively:
use lib qw(.);
require "tool1-lib/config.pl";
use lib qw(.);
require "tool2-lib/config.pl";
This solution isn't good, since while it might work for you now, if you add
another script that wants to use the same module or config.pl file, it would
fail as we saw in the third scenario.
Let's see some better solutions.
.Solution 2
Another option is to use a full path to the script, so it will be used as a
key in %INC;
require "/full/path/to/the/config.pl";
This solution solves the problem of the first two scenarios. I was surprised
that it worked for the third scenario as well!
With this solution you lose some portability.
If you move the tool around in the file system you will have to change the
base directory or write some additional script that will automatically
update the hardcoded path after it was moved.
Of course you will have to remember to invoke it.
.Solution 3
Make sure you read all of this solution.
Declare a package name in the required files! It should be unique in
relation to the rest of the package names you use. %INC will then use the
unique package name for the key.
It's a good idea to use at least two-level package names for your private
modules, e.g. MyProject::Carp and not Carp, since the latter will collide
with an existing standard package.
Even though a package may not exist in the standard distribution now, a
package may come along in a later distribution which collides with a name
you've chosen.
Using a two part package name will help avoid this problem.
Even a better approach is to use three level naming, like
CompanyName::ProjectName::Module, which is most unlikely to have conflicts
with later Perl releases.
Foresee problems like this and save yourself future trouble.
What are the implications of package declaration?
Without package declarations, it is very convenient to use() or require()
files because all the variables and subroutines are part of the main::
package.
Any of them can be used as if they are part of the main script. With package
declarations things are more awkward.
You have to use the Package::function() method to call a subroutine from
Package and to access a global variable $foo inside the same package you
have to write $Package::foo.
Lexically defined variables, those declared with my () inside Package will
be inaccessible from outside the package.
You can leave your scripts unchanged if you import the names of the global
variables and subroutines into the namespace of package main:: like this:
use Module qw(:mysubs sub_b $var1 :myvars);
You can export both subroutines and global variables. Note however that this
method has the disadvantage of consuming more memory for the current
process.
See perldoc Exporter for information about exporting other variables and
symbols.
This completely covers the third scenario. When you use different module
names in package declarations, as explained above, you cover the first two
as well.
Comentário - Estas alternativas inviabiliza a utilização do mod_perl em meu
ambiente sistêmico ( existem vários scripts que utilizam a instrução
require ) e
não seria sensato ter que multiplicá-los para individualizar nomes.
____________________________________________________________________________________________________
Localizei também este texto na internet e não entendi ( meu conhecimento em
perl é limitado )
Code Caching Effects (
http://www.informit.com/articles/article.aspx?p=23010&seqNum=4 )
Recall that mod_perl caches compiled scripts.
This helps it run scripts faster, but what happens if you change a script?
Does mod_perl continue to execute
the cached version? Nope. Apache::Registry keeps track of the scripts that
it has run and checks the modification date of the original file when a
script is requested again.
If the date has changed, it recompiles the script and the new version is
used instead.
You can verify this for yourself. Request a script, and then change it and
click the Reload button in your browser.
You should see the changed output.Then change the script back and click
Reload again.You should see the original output.That's what you expect and
want to happen.2
However, this behavior doesn't apply to modules pulled into your script via
use or require.
If you change those files, the changes won't be noticed until you restart
the server.
Another workaround for this problem is to use the Apache::StatINC module,
which forces Apache to check the last modification time even for modules
referenced from use or require statements.
This is a technique best used on a development server, because it slows down
Apache. Run perldoc Apache::StatINC from the command line for more
information.
Script caching also is responsible for another mysterious problem.
If you use or require a library file, that file's code is pulled in to your
script, compiled, and cached, as usual.
If the file doesn't contain a package declaration to specify a namespace,
however, the code goes into your script's own namespace.
This is main when you run scripts in standalone mode, but scripts run in
their own unique namespace under mod_perl.
If your script is called script.pl, for example, the namespace might be
&Apache::ROOT::cgi_2dperl::script_2epl.
Normally, having unique namespaces per script is a good thing, because it
helps keep scripts that are run under a given httpd child from colliding
with each other in the main namespace.
But it causes a problem for unpackaged library code. Here's why: Suppose you
run your script script.pl that uses a library file MyLib.pm containing a
function lib_func(). script.pl will execute properly.
Now suppose you have a second script, script2.pl, that wants to use
MyLib.pm, too.When the second script, executes, mod_perl, sees the use or
require line for the library file,
notices that the file has already been processed and cached, and doesn't
bother to recompile it.Then when script2.pl calls lib_func() from the
library file, an error occurs:
[error] Undefined subroutine
&Apache::ROOT::cgi_2dperl::script2_2epl::lib_func called
This happens because functions in the library file have been compiled, but
they're in the namespace for script.pl, not script2.pl.To fix this problem,
make sure the library file includes a package declaration, and then invoke
its functions using the package identifier. MyLib.pm can be written like
this:
package MyLib;
sub lib_func
{
...
}
...
After making that change, your scripts should invoke MyLib::lib_func()
rather than lib_func().
Alguém sabe como resolver este problema ?
Agradeço a atenção dispensada ,
kleber
Mais detalhes sobre a lista de discussão Cascavel-pm