views:

102

answers:

3

I'm in a situation where a module I'm using has a function that's name is exactly the same as one in my own module. When I try to call the function in my module (OO Perl, so $self->function) it's calling the function from the other module instead.

I've already got around it by renaming my function but as a matter of interest, is there any way of explicitly calling the function from my module?

edit: this is essentially what I'm doing

package Provider::WTO;

use base qw(Provider); # Provider contains a method called date

use utilities::utils; #not my module so don't blame me for the horrendous name :-)
...
sub _get_location
{
    my $self = shift;
    return $self->date."/some_other_string"; # calls utilities::utils::date()
}

TIA

A: 

Are you sure this is happening in a method call (i.e. $self->function) and not a regular call?

If that's the case, then the only way I can see of that happening is your module is extending the other module, and you're not defining the method in question, and the module you're extending defines a function with the same name as the method you're trying to call.

In any case, you can not import the offending function into your namespace with use Foreign::Module ().

If it's a regular function call that's getting clobbered, you can refer to it as Your::Module->function.

Pedro Silva
It's definitely a method call
Mark
and the rest of the comment, are you using this other module as a super class of yours?
MkV
Definitely not, but you've jogged my memory. The class the method is called in is a descendant of the class the method is defined in. Does that make a difference?
Mark
@Pedro it's an imported function shadowing an inherited method.
hobbs
ok...isn't that what I said? And why the downvote?
Pedro Silva
Oh, ok, that's not what I said. Sorry.
Pedro Silva
+7  A: 

If the name conflict is caused by an import from another module you might consider either Sub::Import, which allows for easy renaming of imports, even if the exporting module doesn't explicitly support that, or namespace::autoclean/namespace::clean.

package YourPackage;

use Sub::Import 'Some::Module' => (
    foo => { -as => 'moo' },
); # imports foo as moo

sub foo { # your own foo()
    return moo() * 2; # call Some::Module::foo() as moo()
}

The namespace cleaning modules will only be helpful if the import is shadowing any of your methods with a function, not in any other case:

package YourPackage;

use Some::Module; # imports foo
use Method::Signatures::Simple
use namespace::autoclean; # or use namespace::clean -except => 'meta';

method foo {
    return foo() * 2; # call imported thing as a function
}

method bar {
    return $self->foo; # call own foo() as a method
}

1;

This way the imported function will be removed after compiling your module, when the function calls to foo() are already bound to the import. Later, at your modules runtime, a method called foo will be installed instead. Method resolution always happens at runtime, so any method calls to ->foo will be resolved to your own method.

Alternatively, you can always call a function by it's fully-qualified name, and don't import it.

use Some::Module ();
Some::Module::foo();

This can also be done for methods, completely disabling runtime method lookup:

$obj->Some::Module::foo();

However, needing to do this is usually a sign of bad design and you should probably step back a little and explain what you did to get you into this situation in the first place.

rafl
+3  A: 

Do you need that subroutine from the offending module? Without knowing more about it, I think the quick fix is to explicitly not import it with an empty import list:

 use Interfering::Module ();

If you need other imported things, you can specify the ones that you need:

 use Interfering::Module qw(sub1 sub2);

If the list of exports you want is really long, you can just exclude the interfering subroutine:

 use Interfering::Module qw(!bad_sub);

If none of those work, you'll have to say more about the interfering module.

brian d foy
The offending module doesn't define @EXPORT or @EXPORT_OK so that would automatically import every function wouldn't it?
Mark
No, the opposite usually. Without @EXPORT, nothing is usually imported. Does it use Exporter though? If it defines its own import() routine, it can do whatever it wants. What happens when you try my advice?
brian d foy
No, it's just a .pm file that defines a bunch of functions. Even if I only import the functions I want (not including date) it still calls the wrong date function.
Mark
Does this file declare it's own package? That would separate it's subroutines from those in the current package. It sounds like you need to fix that module to play well with others.
brian d foy