Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Namespaces & colliding names

by jahero (Pilgrim)
on Nov 08, 2016 at 08:10 UTC ( [id://1175518]=perlquestion: print w/replies, xml ) Need Help??

jahero has asked for the wisdom of the Perl Monks concerning the following question:

Hello wise monks!

I would like to ask a (probably) newbie question in regards to namespaces and names collisions.

Lets say that I have something like this in my code (shortened, incomplete).

package Something::BufferedRead; use strict; use warnings FATAL => 'all'; use File::Basename; our $VERSION = 1.00; my $BUFFER_SIZE = 1048576; sub new { my $class = shift; my @data = @_; my $self = {}; bless $self, $class; return $self; } sub basename { my $self = shift; return basename($self->{cfg}->{filename}); }

Now this fails to compile since 'basename' collides with name of sub imported from module File::Basename. Obvious solution would be to change name of my sub, for example to 'base_name', however I want to understand what exactly is going on, and how to prevent this from being pain in the future.

Which leads me to the real question.

  • Is there aby way how to prevent File:::Basename->basename from becoming a member of Something::BufferedRead namespace?
  • How exactly does one influence what is imported from the module used? I am sure this has something to do with Exporter module and/or import methods, but details slip from grasp.
  • What mechanism could I use to be able to declare 'basename' sub in my sub, and still have File::Basename->basename at my disposal?

Thank you for your time!

Replies are listed 'Best First'.
Re: Namespaces & colliding names
by Athanasius (Archbishop) on Nov 08, 2016 at 08:24 UTC

    Hello jahero, and welcome to the Monastery!

    You can control what is imported by specifying imports explicitly as part of the use declaration. For example, if you change your code to:

    use File::Basename ();

    then the basename function in File::Basename will not be imported, so defining your own sub basename will not produce a namespace collision. If you then wanted to call the function of that name in File::Basename, you would need to qualify it fully:

    File::Basename::basename(...);

    See the documentation for use.

    Hope that helps,

    Athanasius <°(((><contra mundum Iustus alius egestas vitae, eros Piratica,

      Yes, this helps. Thank you for explanation!

Re: Namespaces & colliding names
by kcott (Archbishop) on Nov 08, 2016 at 09:26 UTC

    G'day jahero,

    Welcome to the Monastery.

    ++Athanasius showed in his response how to stop all imports with:

    use File::Basename ();

    However, there may be cases where you only want to stop some, but not all, imports. Still using File::Basename as an example, let's say you wanted its dirname() function. You can specify importation of that function like this:

    use File::Basename qw{dirname};

    Module documentation will often identify which functions are exported by default and which are optionally exported; however, presence of this information is by no means guaranteed. You can check for yourself by looking at the source code: @EXPORT lists the default exports and @EXPORT_OK lists the optional ones. For example, the File::Basename source code shows four default exports:

    @EXPORT = qw(fileparse fileparse_set_fstype basename dirname);

    See Exporter for a lot more information on this including advanced features. For instance, to exclude basename() only, you could write:

    use File::Basename qw{!basename};

    — Ken

      Thank you, I was not aware that one can also exclude certain parts of the module from import.
Re: Namespaces & colliding names
by shawnhcorey (Friar) on Nov 08, 2016 at 14:18 UTC

    You could also rename File::Basename::basename

    use File::Basename (); local *file_basename = \&File::Basename::basename; say file_basename( $0 );
      This leads me to understanding another concept I had trouble understanding - typeglobs. Thanks for that.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1175518]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (5)
As of 2024-04-19 22:50 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found