Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Re^3: Should Modules Do I/O?

by BrowserUk (Patriarch)
on Mar 18, 2005 at 19:06 UTC ( [id://440780]=note: print w/replies, xml ) Need Help??


in reply to Re^2: Should Modules Do I/O?
in thread Should Modules Do I/O?

both interfaces be supported

Providing both seems like YALORC to me. Yet Another Lump Of Reduntant Code,

Your post would make it three

With the interface I describe, the other two interfaces can be trivially derived through subclassing, or just simple procedural wrappers.

That could be done as a part of the module, but I see no value-add in that, as it is equally trivial for the user To Do It themselves, and they can tailor it to their exact requirements, instead of having to work around the supplied interface.

Neither of the other two interfaces can be easily wrapped to provide each other, nor that which I described.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco.
Rule 1 has a caveat! -- Who broke the cabal?

Replies are listed 'Best First'.
Re^4: Should Modules Do I/O?
by Mugatu (Monk) on Mar 18, 2005 at 20:57 UTC

    As you acknowledge, these three interfaces can be implemented using eachother. The higher level methods can use the lower level methods. There is nothing redundant there.

    Nobody is suggesting that the OP should make one and only one interface available, except you (unless I am misunderstanding your position). Few users will have to "work around the supplied interface" if the interface embodies the common usage scenarios. That is the value-add.

      As you acknowledge, these three interfaces can be implemented using eachother.

      I did not acknowledge that--I flat out contradicted it.

      Neither of the other two interfaces can be easily wrapped to provide each other, nor that which I described.

      And I'm not sure how you came to that reading from my post?

      Nobody is suggesting that the OP should make one and only one interface available, except you (unless I am misunderstanding your position).

      You are not misunderstanding my position. I think that a single flexible interface is prefereable to multiple overlapping interfaces. Adding bloat to a module is detrimental rather than value-add IMO.

      If there are common usage scenarios that would benefit from a simpler interface, these should be provided through a separate package that wraps the flexible interface in the same way that LWP::Simple wrap LWP::Useragent and XML::Simple wraps either XML::Parser or XML::SAX.

      I'm not into deeply nested hierachies, but two levels strikes a good balance between depth and breadth at all levels.

    • It allows the segregation of the code for both maintenance and use.
    • It allows the *::Simple documentation to be exactly that, rather than mixing it up with the complexities of the full interface.
    • The *::Simple module becomes an excellent "API design" test, and long-term regression test for the primary module.
    • It also serves as a "worked example" of both using the primary module and extending it.

      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco.
      Rule 1 has a caveat! -- Who broke the cabal?
        As you acknowledge, these three interfaces can be implemented using eachother.
        I did not acknowledge that--I flat out contradicted it ... And I'm not sure how you came to that reading from my post?

        I was talking about this sentence:

        With the interface I describe, the other two interfaces can be trivially derived through subclassing, or just simple procedural wrappers.

        What you call trivially derived is what I meant when I said implemented using eachother. Just to make it even more clear, I meant you can make the filehandle interface, and have the other interfaces use that.

        If there are common usage scenarios that would benefit from a simpler interface, these should be provided through a separate package that wraps the flexible interface

        This is six of one or half dozen of the other. If you insist on moving the simple interfaces into a ::Simple module, so be it. But it should be made from the beginning, otherwise there will be users who end up writing code they shouldn't have to write.

        Frankly, I think that the more good interfaces there are available, the better. It can be done cleanly, and it can be done without "adding bloat to a module." Your position on this matter flies in the face of my years of experience using Perl.

        PS: I will not reply any further. I have said about all I can on this subject. Please feel free to respond, but don't expect me to.

Re^4: Should Modules Do I/O?
by Tanktalus (Canon) on Mar 18, 2005 at 21:54 UTC
    sub get_file { my $self = shift; my $filename = shift; my $outputdir = shift; my $ofh = IO::File->new(File::Spec->catfile($outputdir, $filename), +'w'); $self->get_filehandle($ofh); }
    The amount of code I get to save by having this in the module is awesome. And, thus, the number of bugs I'll have in this code will be darned few. Approaching zero the second time I use it.

    Redundant is writing the above 12 times rather than having a single sub doing it for me.

      Agreed.

      But what if I want read access? Or read-write access? Or read the file from a pipe?

      Of course, you can fix up your sub to deal with all of these things, but then you've reinvented open, which exists, is tested and supported everywhere, and can do all of those and more.

      What-if you need to read from a socket? Or you need access to acls? Or security attributes? Or named-pipes? Or...

      And if the OP's module also has that same snippet of code? Which is the redundant one?

      And Another::Module also has it, but dies if the file could not be found?

      And Bother::Module has it, but always, silently, overwrites any existing file?


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco.
      Rule 1 has a caveat! -- Who broke the cabal?

        Isn't that what $self->get_filehandle from my snippet was supposed to handle? If a common case for using a module is to save to files (e.g., Archive::Tar, File::Copy), then it makes sense to allow filenames, output directories, etc., as a simple interface, and allow file handles as a generic interface (for sockets, etc.). I'd hate to see 30% of the users of a module have to write the same 5 lines of code just to get out a single file of an archive - that's what modules are for in the first place. (e.g., IO::Select - does that ever save a lot of common code!)

        If you want to do some other funkiness, great - you can still use the more generic interface.

        To be honest, I've got one module that provides three interfaces: filename, file handle, and callback. And, when using that module, I use all three, depending on the situation. (Oddly, only the file handle is implemented at the lowest level - the other two are implemented in terms of the file handle.) The whole purpose of the module is file storage, so it makes sense to be able to specify the file name and just let the module do the work. That's kinda where I'm coming from on this, I suppose.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (5)
As of 2024-04-16 18:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found