Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Re^3: Module's name and file's name

by muba (Priest)
on Jan 23, 2013 at 11:09 UTC ( #1014882=note: print w/ replies, xml ) Need Help??


in reply to Re^2: Module's name and file's name
in thread Module's name and file's name

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?


Comment on Re^3: Module's name and file's name
Select or Download Code

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others pondering the Monastery: (3)
As of 2014-07-13 05:20 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    When choosing user names for websites, I prefer to use:








    Results (246 votes), past polls