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

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.

Replies are listed 'Best First'.
Re^5: Should Modules Do I/O?
by BrowserUk (Patriarch) on Mar 18, 2005 at 22:12 UTC

    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.

        Isn't that what $self->get_filehandle from my snippet was supposed to handle?

        How can it? get_file() is hard-coded to use a mode of 'w' (which doesn't make sense to me? does 'get' imply 'read'?), and it returns a filehandle.

        Which you then pass to a method called get_filehandle()--but you already have one, so what is get_filehandle() going to do with it?

        And why is it called 'get_filehandle()' if I have to give it a filehandle?

        Archives can be existing or new, read from or written to, or both.

        So, either you provide a full interface to open, or your making big assumptions (and imposing restrictions) upon what the user might need to do.

        Quite frankly, I'm totally lost as to what your code snippet was meant to show, or how it relates to this thread? I'm probably missing something that is obvious to you, but please forgive my stupidity and explain 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?