Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

Re: Module's name and file's name

by tobyink (Canon)
on Jan 22, 2013 at 20:34 UTC ( [id://1014782]=note: print w/replies, xml ) Need Help??


in reply to Module's name and file's name

Modules (i.e. ".pm" files containing Perl code) and packages (i.e. namespaces that subs and variables can be defined in) are two different things. There is no rule that says you must keep their names aligned.

However, when you do align their names, certain Perl features work in your favour - for example, the use statement. use Foo::Bar is defined to load the file Foo/Bar.pm and then call the import method in the Foo::Bar package. This feature is super-handy when the Foo::Bar package happens to be defined within the file Foo/Bar.pm; less so when it isn't.

If you know what you're doing, and are aware of the order in which Perl processes things, how use works, etc, then it's sometimes possible to break the alignment in useful ways. For example, keeping several small packages in the same file can make sense - it will improve load speed, they can share lexical variables, etc.

But for the most part, unless you have a specific reason not to, you should try to keep package names and module names aligned.

package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name

Replies are listed 'Best First'.
Re^2: Module's name and file's name
by beurive.denis (Novice) on Jan 22, 2013 at 20:48 UTC

    Thank you for your response.

    The modules I used today have something bad. I thought It was because the names of the module and the name of the file are not aligned.

    When I use them from a command line script, everything works fine.

    But if I use them within a Dancer's (the CPAN module "Dancer") application… it is a big mess. Many variables "become" suddenly undefined…

    Note : these modules have been written in a hurry by some developers that don't respect good pratices (no "use strict", no naming conventions for variables or functions…).

    So I use these modules through "system()" (that is, in a totally separated environment)… It's really bad, but, at least, it works…

    Well, it is something else. I'll try to find out if I have some time.

    Bets regards

    Denis

      This piqued my curiosity. What do you mean, you "use these modules through system()?" Do you just call system("perl MyModlue.pm")? Are you quite sure this "module" is actually a module, in the sense that in defines a handful of subroutines or perhaps an object class, either way a bunch of code that doesn't do much until you tell it to? Or is it really a full fledged script that you actually run, maybe as a part of a larger system or maybe not, but a script nontheless?

      When I think module, I think abstraction layer. For example, an example of modules that you could write for some project are:

      • a socket factory, which creates IO::Socket::INET objects to connect to a range of servers,
      • a simple object class that wraps around IO::Select, which reads from as much sockets as possible (i.e. all sockets that have data for me), remembers which sockets it took input from, and then hands that input back to my main code. More than than, as it reads the input from a socket, it already molds it into a form that will be easy to work with in the main code. Later on, the object will be able to send meaningful responses back to those sockets. It will also close connections that are no longer needed.
      • a module that processes the input data, stores relevant information in a log file, and returns a list of results
      • There happens a bunch of other things "under the hood", but in essence this way of working allows my code to kinda look like this:

        use strict; use warnings; use SocketFactory; use IoSelectWrapper; use InputHandler; # all of these could use better names... ;) use More::Stuff; # ... my @hosts = More::Stuff::get_hostnames(); my $sock_fac = SocketFactory->new; $sock_fac->connect( @hosts ); my $io = IoSelectWrapper->new( $sock_fac->sockets ) main_loop($reader); sub main_loop { my $io = shift; my $handler = InputHandler->new; while ( defined(my $input = $io->get_next) ) { $handler->add( $input ); if ($io->is_complete) { $io->reply( $handler->handle ); } } }

        This is very much a simplification, but what's relevant here is that the main code is easy to read. From top to bottom, it tells Perl to get the hostnames, connect to them, wrap an IO abstraction layer around those connections, and enter the main loop. Inside the main loop, create an input handler, get a chucnk of input from the IO wrapper, and feed that input to the handler. When the IO wrapper says it has collected a complete set of input chunks, tell the handler to do its work and hand the result back to the IO wrapper. Then read the next chunk of input until there's nothing more to read.

        The (imaginary) fact that InputHandler.pm is almost 1000 lines of code, IoSelectWrapper.pm is just over 400 lines, SocketFactory.pm about 100, and More::Stuff is actually 6 different files totalling to around 6000 lines, is completely invisible from the main code. The main code is short, simple, and abstract. All the gory details of creating sockets, connecting to other servers, maintaining those connections, reading data, parsing data, processing that data, and logging the act of processing, are neatly hiddden in their own relevant modules.

        Note that none of these modules can run stand-alone. They're all part of a bigger system. IoSelectWrapper, for example, wouldn't have anything to read from without More::Stuff kindly opening connections for it, and InputHandler can't do a thing until IoSelectWrapper begins spitting out data. Also note that none of these modules do a thing until the main code tells them to. IoSelectWrapper just sits around, staring at its nails, only to occasionally read from a few sockets once every iteration. InputHandler is standing in the corner, soaking up everything it sees until its told to process all of that, and while it's processing, IoSelectWrapper can't even get a cup of coffee because this program doesn't use threads or call fork, so everybody in the room waits until InputHandler comes back with its results.

        Most of these modules use other modules in turn. For example, SocketFactory will use IO::Socket::INET at the least, IoSelectWrapper surely uses IO::Select and what-else-you've-got. It's likely that they're both built using Moose or Moo or a similar framework.

        To come back to my point, when I think module, I think long wall of code, doing all sorts of useful things for me, such that I don't have to bother how it does it. I think subroutines or methods that I will pump data into and that will throw something back at me, and possibly I think of import lists or tags, if the module is written to export stuff. Which my modules are hardly ever — I'm an OO junkie.

        I think all that when I think module. I definitely don't think system(...). So I'm wondering, are your "modules" modules? Or are they stand-alone scripts that nevertheless could be part of a bigger system?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1014782]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others imbibing at the Monastery: (4)
As of 2024-04-16 04:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found