]> gitweb.factorcode.org Git - factor.git/blob - core/destructors/destructors-docs.factor
c82f92dc102817117472b25dc179dc3d5140e463
[factor.git] / core / destructors / destructors-docs.factor
1 USING: help.markup help.syntax libc kernel continuations io
2 sequences ;
3 IN: destructors
4
5 HELP: dispose
6 { $values { "disposable" "a disposable object" } }
7 { $contract "Releases operating system resources associated with a disposable object. Disposable objects include streams, memory mapped files, and so on."
8 $nl
9 "No further operations can be performed on a disposable object after this call."
10 $nl
11 "Disposing an object which has already been disposed should have no effect, and in particular it should not fail with an error. To help implement this pattern, add a " { $snippet "disposed" } " slot to your object and implement the " { $link dispose* } " method instead." }
12 { $notes "You must close disposable objects after you are finished working with them, to avoid leaking operating system resources. A convenient way to automate this is by using the " { $link with-disposal } " word."
13 $nl
14 "The default implementation assumes the object has a " { $snippet "disposable" } " slot. If the slot is set to " { $link f } ", it calls " { $link dispose* } " and sets the slot to " { $link f } "." } ;
15
16 HELP: dispose*
17 { $values { "disposable" "a disposable object" } }
18 { $contract "Releases operating system resources associated with a disposable object. Disposable objects include streams, memory mapped files, and so on." }
19 { $notes
20     "This word should not be called directly. It can be implemented on objects with a " { $snippet "disposable" } " slot to ensure that the object is only disposed once."
21 } ;
22
23 HELP: with-disposal
24 { $values { "object" "a disposable object" } { "quot" "a quotation with stack effect " { $snippet "( object -- )" } } }
25 { $description "Calls the quotation, disposing the object with " { $link dispose } " after the quotation returns or if it throws an error." } ;
26
27 HELP: with-destructors
28 { $values { "quot" "a quotation" } }
29 { $description "Calls a quotation within a new dynamic scope. This quotation may register destructors, on any object, by wrapping the object in a destructor and implementing " { $link dispose } " on that object type.  After the quotation finishes, if an error was thrown, all destructors are called and the error is then rethrown.  However, if the quotation was successful, only those destructors created with an 'always cleanup' flag will be destroyed." }
30 { $notes
31     "Destructors generalize " { $link with-disposal } ". The following two lines are equivalent, except that the second line establishes a new dynamic scope:"
32     { $code
33         "[ X ] with-disposal"
34         "[ &dispose X ] with-destructors"
35     }
36 }
37 { $examples
38     { $code "[ 10 malloc &free ] with-destructors" }
39 } ;
40
41 HELP: &dispose
42 { $values { "disposable" "a disposable object" } }
43 { $description "Marks the object for unconditional disposal at the end of the current " { $link with-destructors } " scope." } ;
44
45 HELP: |dispose
46 { $values { "disposable" "a disposable object" } }
47 { $description "Marks the object for disposal in the event of an error at the end of the current " { $link with-destructors } " scope." } ;
48
49 HELP: dispose-each
50 { $values
51      { "seq" sequence } }
52 { $description "Attempts to dispose of each element of a sequence and collects all of the errors into a sequence. If any errors are thrown during disposal, the last error is rethrown after all objects have been disposed." } ;
53
54 ARTICLE: "destructors-anti-patterns" "Resource disposal anti-patterns"
55 "Words which create objects corresponding to external resources should always be used with " { $link with-disposal } ". The following code is wrong:"
56 { $code
57     "<external-resource> ... do stuff ... dispose"
58 }
59 "The reason being that if " { $snippet "do stuff" } " throws an error, the resource will not be disposed of. The most important case where this can occur is with I/O streams, and the correct solution is to always use " { $link with-input-stream } " and " { $link with-output-stream } "; see " { $link "stdio" } " for details." ;
60
61 ARTICLE: "destructors" "Deterministic resource disposal"
62 "Operating system resources such as streams, memory mapped files, and so on are not managed by Factor's garbage collector and must be released when you are done with them. Failing to release a resource can lead to reduced performance and instability."
63 $nl
64 "Disposable object protocol:"
65 { $subsection dispose }
66 { $subsection dispose* }
67 "Utility word for scoped disposal:"
68 { $subsection with-disposal }
69 "Utility word for disposing multiple objects:"
70 { $subsection dispose-each }
71 "Utility words for more complex disposal patterns:"
72 { $subsection with-destructors }
73 { $subsection &dispose }
74 { $subsection |dispose }
75 { $subsection "destructors-anti-patterns" } ;
76
77 ABOUT: "destructors"