Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

Re^2: Perl Modules

by jamroll (Beadle)
on Jun 20, 2017 at 20:27 UTC ( #1193178=note: print w/replies, xml ) Need Help??

in reply to Re: Perl Modules
in thread Perl Modules

i'm not opposed to books. they are great. i've read many. the one you suggest is not one i have read. so ... i will check it out. most folks generally point me in the direction of the tutorials and documents one can easily find. but, none address the issue i'm having. most just talk about one module, and not many that interact together and require each other in circus - sometimes two modules need each other in order to do their job. i think this is the underlying problem i'm having, but i can't be 100% certain. mainly because I lack a group of friends whom i can have a face to face conversation with. one man band kinda sucks, but i'm determined to get this site up and going!

Replies are listed 'Best First'.
Re^3: Perl Modules -- abstraction and interfaces
by Discipulus (Abbot) on Jun 20, 2017 at 22:20 UTC
    hello jamroll,

    your thread is long and somehow confusing, but here you say something that captured my attention:

    > many that interact together and require each other in circus

    First some firm stone, to not let confusion overhelm us: Some::Module must be in Some/ and this path must be in @INC or added to it at runtime using -I perl switch. See perlmod (and perlrun for the perl switch). Also notice that you (i think is not a constrain but more a convention) you start Some::Module declaring a package with the same name package Some::Module; ( PS read tobyink's wise advices in Re: Module's name and file's name )

    Second: the easy way is to use Exporter; and fill @EXPORT_OK with every sub you want to be usable (with use ..) by other programs or modules. All sub you put in @EXPORT will be exported by default, generally not what you want.

    After this basic level abstraction will be the keyword. I have a little experience but when I ended with a module as a an unorderd collection of subs i know i was on the looser path.

    For such reason choosing rigth names(spaces) for your modules is so hard, generally harder than choosing sub names. They reflect how you approached the problem/subject you'll resolve with you programs. In more complex cases you can have entire trees of modules with the deeper ones specializing the parent: like Project::Display will be responsable to compose messages to be shown and Project::Display::Console and Project::Display::HTML will handle differnt display types.

    Nothing bad if Project::Logger uses a facility sub you defined in Project::Display .If you are always sure where you put your subs and you export the sub correctly everybody is happy.

    Once a wise programmer said "progrimming is a matter of interfaces" and is true. A lot true. If your module just exposes a mixed collection of beahviours this will no matter a lot. But when you find that some subs in your module are, and possibly must remain, private to such module, you are implicitly thinking an interface.

    Consider having a Project::Postman that is used to send out mails: the module can just expose one or few subs but can have dozen of private subs to check mail addresses, availability of smtp servers.. Less you expose and as much as this remain stable, more you will be able to change internally Project::Postman without braking any program that uses, consumes your module.

    More you stress this in your programs more you tend to just expose one sigle sub that return a scalar, or an object if you want, that is autosufficient and knows who it is and what behaviour to put in the field.

    As much will be easy for you to do such name/functionality abstraction, as much you'll be closer to Object Oriented programming, easy to realize using Perl, with or without OO frameworks.

    As always you have a lot of different options you must follow your inclination or needs of particular projects.


    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
      i thoroughly enjoyed that read! :D you got it bang on! thank you for taking the time to help me on this issue. your reply answered a few questions, yes! that was most useful, uh huh.

      so...if i have project::display and does html use the methods/subs within display? are they inherited into html automagically? blarg! i'm confusing myself...but, do you get what i'm asking? this is why i posted this question as i did, because I haven't a clue what i'm asking, but i need to know it in the worst way lol

        hello again jamroll,

        I'm for sure not the best monk in the monastery to explain this, but it seems you liked my way to express it.

        > are they inherited into html (package I'd add) automagically?

        No, they are not. You have two options:

        The plain, easy way: is let Exporter to do his job via @EXPORT_OK as already said. Read through manual to know more about it.

        Everything in your module Project::Display (capitalize first char as idiomatic (idiomatic IS good thing) common practice), module that use Exporter (and also Project::Display states that @ISA = qw(Exporter); but more on this later) every sub defined in your module and that also is in @EXPORT_OK can be usable from other scripts or modules that include something like use Project::Display qw(a_sub_you_put_in_EXPORTER_OK another_one etc); and this is good.

        Keep the whole thing simple, well named, ordered, and with some sense and everything will run smooth.

        The ObjectOriented way: in this path to know a little of terminology is another good thing to do: perldoc has perlglossary just in case, but for Objected Oriented Perl (OO for brevity) the principal source of wisdom will be object oriented fundamentals that is in perlootut

        Going to this path maybe trickier, but perhaps you are more inclined to program OO than in other ways. One of basic concepts is inheritance: with the already seen @ISA you put in your Project::Display module you asserted that your module IS-A Exporter: practically if a method (new term from OO, but is simply a sub..) is not found in Project::Display will be searched into every module (well package) you put into @ISA array.

        So Project::Display::Console and Project::Display::HTML will both have @ISA = qw (Project::Display); very soon stated.

        You than in your consumer script that uses this modules/classes you create an object, a simple scalar emitted by a constructor defined in the module: by tradition that special constructor sub, defined in a module/class/package is named new and this sub will bless that scalar: ie it marks this scalar as belonging to a particular module/class/package.

        Doing so you will be able to do my $tv = Project::Display->new ( more=> "params", can_be => "supplied"); in your script and if Project::Display defines a sub format_70_chars then your $tv object can call this method: $tv->format_70_chars( $some_text );

        But now you want to use inheritance and want to sublcass Project::Display and have a handy Project::Display::Console class to be able to draw text into a boxes done with - and | signs.

        You create this package/module/class stating that this package @ISA is a Project::Display object. This Project::Display::Console will NOT have his own new method: it inherits it directly form Project::Display (you'll learn how to accomplish this correctly) but this new class just define a draw_in_box method.

        If everything is wrote correctly only an objected created as instance of the class Project::Display::Console can call draw_in_box while objects created as Project::Display::HTML cannot. But both ojects inherits the new method from Project::Display base class.

        Take a read of perlobj and consider to read the objects part of the must have ModernPerl free book (even if it just show the Moose implementation and not the plain perl OO I showed you).

        ouch! i wrote a lot! read your manual now!


        There are no rules, there are no thumbs..
        Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

Log In?

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

How do I use this? | Other CB clients
Other Users?
Others surveying the Monastery: (7)
As of 2021-06-13 12:22 GMT
Find Nodes?
    Voting Booth?
    What does the "s" stand for in "perls"? (Whence perls)

    Results (55 votes). Check out past polls.