Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Re^5: Should Modules Do I/O?

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


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

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?

Replies are listed 'Best First'.
Re^6: Should Modules Do I/O?
by Tanktalus (Canon) on Mar 18, 2005 at 22:51 UTC

    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?

        I think I'll address your post a little backwards. "Stupidity"? Communication is a two-way street, and thus it's rarely one-sided on a failure. In this case, I think I have to shoulder more of the blame of your misunderstanding than you do ;-)

        I had it my head the example of Archive::Tar. I'm not entirely sure why (was there a recent thread on this module or something that could be sticking in my head?). So when I say "$obj->get_file", I'm thinking that we're telling the "$obj"ect to get a file from the archive (or, more generally, from whatever source it is encapsulating, e.g., a cache, an FTP server, a web server, a zip file, a jar file, whatever). In this scenario, in all likeliness, well over 80% of the time, you want to get the file from the encapsulated location, and put it somewhere locally. This is where having a simple function that does I/O makes sense. For the other < 20% of the time, I agree that the file handle interface makes the most sense (some encapsulated data types may make more sense to use the callback, e.g., sockets such as FTP, where you still want the object to handle the communication with the remote server, and the overhead of creating a tie'd handle may be too much to bother with, since the end of the file doesn't actually correspond with the end of data through the socket).

        Perhaps a more elaborate set of object methods would be useful:

        sub extract_file # takes a destination directory or filename sub extract_file_via_filehandle # takes a filehandle to write to sub insert_file # takes a source directory and filename sub insert_file_via_filehandle # takes a filename (for inside the arch +ive) and a filehandle (for the source)
        All of these have no return value (as I was thinking for the get_file/get_filehandle above). Yes, with perl, often you can overload these to be the same function which can dynamically figure out the difference between a file name and a filehandle. Sometimes that's not feasable, other times ... well, I'm separating it out here purely to show the dual interface of which I'm supportive.

        You do bring up an interesting question: a way to get a filehandle to which one can write. Unfortunately, that may mean some sort of tied interface - this to allow further action with it (imagine FTP where the connection needs to be maintained, thus closing the filehandle should be somehow prevented, or a dynamic archive where one day you could be writing to a filesystem, another to an FTP server, and another to a RDBMS - some of these would need something tied, such as saving to a blob in a database via chunks). I may have to pursue that myself, actually. It may be a cleaner interface. Thanks ;-)

Log In?
Username:
Password:

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

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

    No recent polls found