pwagyi has asked for the wisdom of the Perl Monks concerning the following question:
Hi monks What’s the idiom for resource management in Perl? Resource could be file handle, ftp connection, mutex lock... In Java, there is try with statement. Python has similar with statement. Is DESTROY method the way to do in Perl?
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Resource management (updated)
by haukex (Archbishop) on Oct 29, 2017 at 06:49 UTC | |
Perl has no exact equivalent of Java's "try-with-resources" mechanism, partly because Perl's exception management is different (e.g. the native open and close don't normally throw an exception, but return false values, so program flow can be handled differently) and because Perl does not have an equivalent of Java's interface java.io.Closeable. Although lexical file handles are closed automatically when they are destroyed, this might not be true for some tied file handles, and although Perl's reference counting means that the time at which objects are destroyed is much more reliable than in Java, I would still not recommend relying on DESTROY for everything*. This is because accidental circular references would prevent objects from being a garbage collected, and also, if one forgets to discard objects early enough, trying to clean up resources during global destruction can cause problems. Another issue is that the different kinds of resources you mentioned have different APIs, so the code to clean them up will be different. So unfortunately the answer to your question is that there is no single idiom built into Perl that applies to all the different resources you mentioned, other than closing them explicitly. However, Perl is of course a very flexible language that allows you to implement some kind of idiomatic/unified resource handling, if you like. How you would best do that depends on the details of your code, e.g. is it OO or not and what kind of resources specifically do you want to manage? Another thing that comes to mind is Try::Tiny, which gives you a nice little try/catch/finally mechanism. * Update: Note that I chose the wording "for everything" carefully. There are of course modules that specifically make use of Perl's reference counting and DESTROY to perform actions at the end of a scope, such as e.g. End or File::pushd (although note how careful the latter has to be not to clobber $@). So it is in theory possible to implement "auto close" behavior this way. However, I've already mentioned the major caveats to be considered, like accidental circular references, or in this case just accidentally storing a reference to the object somewhere else, will interrupt this mechanism. Because of these possible accidents I'd call it (for lack of a better term) less "theoretically reliable" than Java's try. So this is why I recommend against DESTROY for a generalized, idiomatic mechanism - but for situations where the scope is small and you can keep track of the references it may be applicable. | [reply] [d/l] [select] |
by pwagyi (Monk) on Oct 29, 2017 at 10:48 UTC | |
| [reply] |
by roboticus (Chancellor) on Oct 30, 2017 at 00:36 UTC | |
No, that's not what was meant. Normally, you don't have to worry about it, because perl uses reference counting, rather than delayed garbage collector. So once the value is no longer accessible, it's automatically cleaned up. In this respect, perl is much more like C++ with RAII where you can just let the destructor handle cleanup for you. Like this:
If you don't store $FH in some persistent location, then once read_file returns, then 'FileName' is already closed, because $FH is no longer accessible. You need to be careful (i.e. manual management) only when you're persisting the variable:
So don't put resources in global variables, and only use resources for the duration of a subroutine, and you'll rarely need to worry about it. For your XS stuff, you'll either have to manually manage the resource if it's coming from C, or you can make your code object oriented and let DESTROY handle it. If you present a bit more detail of your use case, you can get more specific advice. ...roboticus When your only tool is a hammer, all problems look like your thumb. | [reply] [d/l] [select] |
|
Re: Resource management
by 1nickt (Canon) on Oct 29, 2017 at 04:06 UTC | |
Hi, I am not sure if I understand your question completely. But in general Perl is very DWIM (Do What I Mean). So most resources such as the ones you mentioned, will simply be destroyed when they go out of scope. It's good practice to simply call close() on a filehandle, but if you don't Perl will close it at the end the script or subroutine in which it was opened. Memory is also freed automatically via reference counting. Hope this helps, more details needed if not :-)
The way forward always starts with a minimal test.
| [reply] [d/l] |