summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-07-07 06:37:58 -0700
committerKaz Kylheku <kaz@kylheku.com>2021-07-07 06:37:58 -0700
commit7375b5a42a77eeb3ac3f085b3d026adbb93ad5a9 (patch)
tree399d56dfe53a8ac4c9e89f6c75c6e447d2dacddd
parent381ed03066f89602011d82892fe59d4dfff07e00 (diff)
downloadtxr-7375b5a42a77eeb3ac3f085b3d026adbb93ad5a9.tar.gz
txr-7375b5a42a77eeb3ac3f085b3d026adbb93ad5a9.tar.bz2
txr-7375b5a42a77eeb3ac3f085b3d026adbb93ad5a9.zip
with-resources: undocumented nil skip behavior.
Paul A. Patience discovered the hidden "feature" of with-resourcers, that the three-argument form of the binding (var init cleanup) causes the with-resources form to terminate if init returns nil. The (var init) syntax doesn't generate this logic. * stdlib/with-resources.tl (with-resources): Do not emit the when form unless <= 265 compatibility is in effect. * tests/012/oop-mac.tl: New file. * txr.1: Compat note added.
-rw-r--r--stdlib/with-resources.tl9
-rw-r--r--tests/012/oop-mac.tl18
-rw-r--r--txr.131
3 files changed, 54 insertions, 4 deletions
diff --git a/stdlib/with-resources.tl b/stdlib/with-resources.tl
index 9d4a89c9..e95ed4f9 100644
--- a/stdlib/with-resources.tl
+++ b/stdlib/with-resources.tl
@@ -30,8 +30,13 @@
^(let ((,sym ,init))
(with-resources ,rest ,*body)))
(((sym init . cleanup) . rest)
- ^(let ((,sym ,init))
- (when ,sym
+ (if (and (plusp sys:compat) (<= sys:compat 265))
+ ^(let ((,sym ,init))
+ (when ,sym
+ (unwind-protect
+ (with-resources ,rest ,*body)
+ ,*cleanup)))
+ ^(let ((,sym ,init))
(unwind-protect
(with-resources ,rest ,*body)
,*cleanup))))
diff --git a/tests/012/oop-mac.tl b/tests/012/oop-mac.tl
new file mode 100644
index 00000000..d3c3e480
--- /dev/null
+++ b/tests/012/oop-mac.tl
@@ -0,0 +1,18 @@
+(load "../common")
+
+(test (with-resources ((a nil (list a))
+ (b nil)
+ (c nil (list c)))
+ (list a b c))
+ (nil nil nil))
+
+(test (build
+ (catch
+ (with-resources ((a 1 (add a))
+ (x nil)
+ (b 2 (add b))
+ (y (throw 'out))
+ (z nil t)
+ (c 3 (add c))))
+ (out () (add 4))))
+ (2 1 4))
diff --git a/txr.1 b/txr.1
index 363fedf8..9d5ae2b1 100644
--- a/txr.1
+++ b/txr.1
@@ -47841,6 +47841,14 @@ if no
.metn body-form s
are present.
+.TP* Note:
+
+From its inception, until \*(TX 265,
+.code with-resources
+featured an undocumented behavior. Details are given in the
+COMPATIBILITY section's Compatibility Version Values subsection,
+in the notes for compatibility value 265.
+
.TP* "Example:"
The following expression opens a text file and reads a line from it,
@@ -47853,8 +47861,6 @@ immediately:
(put-line l)))
.brev
-
-
.coNP Special variable @ *unhandled-hook*
The
.code *unhandled-hook*
@@ -82755,6 +82761,27 @@ of these version values, the described behaviors are provided if
is given an argument which is equal or lower. For instance
.code "-C 103"
selects the behaviors described below for version 105, but not those for 102.
+.IP 265
+Until \*(TX 265, the
+.code with-resources
+macro exhibits an undocumented behavior: the three-element binding expression
+.mono
+.meti >> ( var < init << cleanup )
+.onom
+immediately causes the
+.code with-resources
+form to terminate with a return value of
+.code nil
+if the
+.meta init
+form returns
+.codn nil .
+Neither the
+.meta cleanup
+in the same expression, nor any subsequent binding expressions or the body
+of the construct, are evaluated. Prior cleanup forms are evaluated in
+reverse order, as documented. A compatibility value of 265 or less restores
+this behavior.
.IP 262
Selection 262 compatibility restores a wrong behavior which existed between
versions 191 and 262 due to a regression. The wrong behavior is that the