]> gitweb.factorcode.org Git - factor.git/blob - core/destructors/destructors-docs.factor
Disposables are now registered in a global disposables set. To take advantage of...
[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, inherit from the " { $link disposable } " class and implement the " { $link dispose* } " method instead." }
12 { $notes "You must dispose of 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 "disposed" } " slot. If the slot is set to " { $link f } ", it calls " { $link dispose* } " and sets the slot to " { $link t } "." } ;
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 " { $slot "disposed" } " slot to ensure that the object is only disposed once."
21 } ;
22
23 HELP: with-disposal
24 { $values { "object" "a disposable object" } { "quot" { $quotation "( 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 using " { $link &dispose } " or " { $link |dispose } ". The former registers a destructor that will always run whether or not the quotation threw an error, and the latter registers a destructor that only runs if the quotation throws an error. Destructors are run in reverse order from the order in which they were registered." }
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 HELP: disposables
55 { $var-description "Global variable holding all disposable objects which have not been disposed of yet. The " { $link new-disposable } " word adds objects here, and the " { $link dispose } " method on disposables removes them. The " { $link "tools.destructors" } " vocabulary provides some words for working with this data." } ;
56
57 ARTICLE: "destructors-anti-patterns" "Resource disposal anti-patterns"
58 "Words which create objects corresponding to external resources should always be used with " { $link with-disposal } ". The following code is wrong:"
59 { $code
60     "<external-resource> ... do stuff ... dispose"
61 }
62 "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." ;
63
64 ARTICLE: "destructors-using" "Using destructors"
65 "Disposing of an object:"
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
76 ARTICLE: "destructors-extending" "Writing new destructors"
77 "Superclass for disposable objects:"
78 { $subsection disposable }
79 "Parametrized constructor for disposable objects:"
80 { $subsection new-disposable }
81 "Generic disposal word:"
82 { $subsection dispose* }
83 "Global set of disposable objects:"
84 { $subsection disposables } ;
85
86 ARTICLE: "destructors" "Deterministic resource disposal"
87 "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."
88 { $subsection "destructors-using" }
89 { $subsection "destructors-extending" }
90 { $subsection "destructors-anti-patterns" }
91 { $see-also "tools.destructors" } ;
92
93 ABOUT: "destructors"