I'm learning CL, and I have minimal experience in other languages. Could someone explain to me in layman terms what this means, especially what "out" here represents, and how it all fits together:
(defun save-db (filename)
(with-open-file (out filename
:direction :output
:if-exists :supersede)
(with-standard-io-syntax
(print *db* out))))
Mostly, the bit I don't understand is "out", but an explanation of the whole thing would be nice.
Thanks
An open file format is a file format for storing digital data, defined by an openly published specification usually maintained by a standards organization, and which can be used and implemented by anyone. Open file format is licensed with open license.
The open() function opens a file, and returns it as a file object.
From the desktop, right-click the desired file. From the drop-down menu, click Open with, then select the desired application. In this example, we'll select Paint. The file will open in the selected application.
Thus, with statement helps avoiding bugs and leaks by ensuring that a resource is properly released when the code using the resource is completely executed. The with statement is popularly used with file streams, as shown above and with Locks, sockets, subprocesses and telnets etc.
Using open() we can use the file handler as long as the file has not been explicitly closed using file_handler. close(), but in case of using with open() context manager, we cannot use a file handler outside the with block. It will raise ValueError: I/O operation on closed file in that case.
out is the stream variable bound to the open file. with-open-file guarantees that the file is open inside the scope, and closed outside the scope, no matter how you exit.
As an addition to ddyer, you can also use MACROEXPAND or MACROEXPAND-1 to see what WITH-OPEN-FILE does:
(macroexpand '(with-open-file (out filename
:direction :output
:if-exists :supersede)
(with-standard-io-syntax
(print *db* out))))
tells us
(LET ((OUT (OPEN FILENAME :DIRECTION :OUTPUT :IF-EXISTS :SUPERSEDE)) (#:G748 T))
(UNWIND-PROTECT
(MULTIPLE-VALUE-PROG1 (PROGN (WITH-STANDARD-IO-SYNTAX (PRINT *DB* OUT)))
(SETQ #:G748 NIL))
(WHEN OUT (CLOSE OUT :ABORT #:G748))))
We can see that we open the file called filename and assign that open file stream to out , and do something. Should something bad happen, UNWIND-PROTECT will CLOSE the stream, should it be non-nil.
The #:G748 variable is a GENSYMed symbol (so it's a fresh, uninterned, symbol). If nothing goes wrong writing the file, we set #:G748 to nil.
Thus, when we CLOSE the stream, if something went wrong #:G748 will be T, so CLOSE will attempt to clean up any side effects of having created the stream.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With