Sean
Sean

Reputation: 645

Apache fastcgi: is there a means to dynamically check an ENV value at subroutine use?

I apologize if the problem definition is a bit disjointed. We have been attacking this issue on many different vectors.

Basic description, we have a website we are trying to provide translations for using Locale::TextDomain

We have fastcgi scripts, that call our local library of perl modules. Fastcgi and translation is tricky (as we are using it) because the language is set at the launch of the script and persists.

So in our library of perl modules this works.

package SR::Locale;
our $LOCALE_NAMESPACE = 'es';
use Locale::TextDomain::UTF8 qw( $LOCALE_NAMESPACE );
our $word = __("football");

But we can't figure out a means to dynamically set the variable $LOCALE_NAMESPACE at startup. We'd like to set it based on the request_uri or the dir path of the script being executed or something like that. So we'd like to do something like, but we can't figure this out in a fast cgi setting:

package SR::Locale;
$ENV{REQUEST_URI} =~ m{example.com/(..)/}
our $LOCALE_NAMESPACE = $1;
use Locale::TextDomain::UTF8 qw( $LOCALE_NAMESPACE );
our $word = __("football");

in this example (for a fastcgi), $ENV{REQUEST_URI} is blank in the module at script start.

Any help would be much appreciated. I have not been able to find any references to translation and fastcgi working together in perl.

Upvotes: 0

Views: 109

Answers (2)

zdim
zdim

Reputation: 66899

One clear problem is that the runtime assignment to $LOCALE_NAMESPACE, that uses the capture from regex on $ENV{REQUEST_URI}, runs after the use statement where that variable is used, since all use statements run at compile time.

If the sole problem is of how to set $LOCALE_NAMESPACE in time for use, do it in BEGIN phase

package SR::Locale;

my $LOCALE_NAMESPACE;

BEGIN { 
    # Add a check that $ENV{REQUEST_URI} is indeed set by the environment
    ($LOCALE_NAMESPACE) = $ENV{REQUEST_URI} =~ m{example.com/(..)/};
}

use Locale::TextDomain::UTF8 qw( $LOCALE_NAMESPACE );

Don't forget that this BEGIN must come before use statements that rely on it. All code that runs in BEGIN phase is executed in order of its appearance in source files (including any further use statements or BEGIN blocks inside the used modules).

Upvotes: 4

mob
mob

Reputation: 118635

I don't know that much about translation in fastcgi environments, but I do know that use is a compile-time statement, so the use statement in your script would be the first thing that Perl would execute (even before $LOCALE_NAMESPACE is initialized).

The run-time equivalent of use MODULE ARGS is

require MODULE;
MODULE->import(ARGS);

This works sometimes to dynamically configure a module at run-time, though it also has many failure modes.

Upvotes: 1

Related Questions