Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

perl: function name clash

Tags:

module

perl

Let's say, there are two modules is our framework: Handler.pm and Queries.pm

Queries.pm is optional and is being loaded at fastcgi process startup

BEGIN {
&{"check_module_$_"}        () foreach (Queries);

}

sub check_module_queries {
...
    require Eludia::Content::Queries;
...
}

every module function is loaded in one common namespace

now, there are two functions with same name (setup_page_content) in Handler.pm and Queries.pm

setup_page_content is being called in Handler.pm

It looks like original author suggested that Queries.pm:setup_page_content will be called, whenever Queries.pm is loaded

Sometimes it doesn't happen: traceback (obtained via caller ()) in these cases indicates, that setup_page_content was called from module Handler.pm

I logged %INC just before call and it contains Queries.pm and it full path in these cases

This behaviour is inconsistent and pops like in 2-3% of attempts on production installation, mostly when I send two parallel identical http requests. Due amount of effort to reproduce, I doesn't determine yet, whether it is installation specific.

How it will be decided which version of function with same name will be called?

Is it well-defined behaviour?

There should be a reason, original author wrote the code this way

UPDATE

perl version is v5.10.1 built for x86_64-linux-gnu-thread-multi

UPDATE 2

code: Handler.pm and Queries.pm

Queries.pm loading occurs in check_module_queries (BEGIN {} of Eludia.pm),

loaded for every request using Loader.pm (via use Loader.pm <params>)

like image 445
jonny Avatar asked Aug 09 '26 10:08

jonny


2 Answers

I'd like to call Custom.pm:setup_page_content, whenever Custom.pm is loaded

So you'd like to call Custom::setup_page_content when it exists.

if (exists(&Custom::setup_page_content)) {
   Custom::setup_page_content(...);
} else {
   Handler::setup_page_content(...);
}

Sometimes it doesn't happen.

The total lack of information about this prevents me from commenting. Code? Anything?


Is there a way to 'unload' a module but leave it in %INC?

Loading a module is simply running it. You can't "unrun" code. At best, you can manually undo some of the effects of running it. Whether that includes changing %INC or not is entirely up to you.

like image 82
ikegami Avatar answered Aug 11 '26 02:08

ikegami


When there is a namespace collision, the most recently defined/loaded function will take precedence.

like image 25
epylar Avatar answered Aug 11 '26 02:08

epylar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!