;;;----------------------------- (with-open-file (input "/usr/local/widgets/data") ;; No need for "die" like call here b/c WITH-OPEN-FILE will do it ;; automatically. (iter (for line in-stream input using 'read-line) (when (scan "blue" line) (format t "~A~%" line))) ;; No need for explicit CLOSE here b/c WITH-OPEN-FILE will do it ;; automatically. ) ;;;----------------------------- (let ((var *standard-input*)) (mysub var logfile)) ;;;----------------------------- ;; The Perl example here is showing the "object-oriented" style of ;; file manipulation. In CL it isn't any different than the above. ;; However we will use this opportunity to demonstrate how to ;; "manually" open/close a file without WITH-OPEN-FILE. (let ((input (open "/usr/local/widgets/data"))) (iter (for line in-stream input using 'read-line) (setf line (chomp line)) (when (scan "blue" line) (format t "~A~%" line))) ;; Don't do this, either use WITH-OPEN-FILE or use UNWIND-PROTECT as ;; illustrated later. (close line)) ;;;----------------------------- (unwind-protect (progn (iter (for line in-stream *standard-input* using 'read-line) (unless (scan "\\d" line) (warn "No digit found.~%")) (format t "Read: ~A~%" line))) ;; Not normally a good idea to do the following; just matching the ;; Perl. (close *standard-output*)) ;;;----------------------------- ;; No need for explicit die, OPEN will throw an exception. (defparameter *logfile* (open "/tmp/log" :direction :output)) ;;;----------------------------- (close *fh*) ; no need for die() ;;;----------------------------- (let ((*standard-output* *logfile*)) ; switch to *LOGFILE* for output (format t "Countdown initiated ...~%")) ;; return to original output (format t "You have 30 seconds to reach minimum safety distance.~%") ;;;----------------------------- |
;;;----------------------------- ;; For reading is the default, no need for "<" or equivalent. No need ;; for explicit die()-like call either. Note also that you should use ;; WITH-OPEN-FILE instead of a raw OPEN wherever possible. (defparameter *source* (open path)) (defparameter *sink* (open path :direction :output)) ;;;----------------------------- #+sbcl (progn (defparameter *source* (sb-posix:open path sb-posix:o-rdonly)) (defparameter *sink* (sb-posix:open path sb-posix:o-wronly))) ;;;----------------------------- ;; There is no equivalent of Perl's "object-oriented" file interface ;; (arguably, the standard mechanism is already object-oriented). ;;;----------------------------- #+sbcl (progn (defparameter *filehandle* (sb-posix:open name flags)) (defparameter *filehandle* (sb-posix:open name flags perms))) ;;;----------------------------- (defparameter *fh* (open path)) #+sbcl (defparameter *fh* (sb-posix:open path sb-posix:o-rdonly)) ;;;----------------------------- (defparameter *fh* (open path :direction :output)) #+sbcl (defparameter *fh* (sb-posix:open path (logior sb-posix:o-wronly sb-posix:o-trunc sb-posix:o-creat) #o600)) ;;;----------------------------- #+sbcl (progn (defparameter *fh* (sb-posix:open path (logior sb-posix:o-wronly sb-posix:o-excl sb-posix:o-creat))) (defparameter *fh* (sb-posix:open path (logior sb-posix:o-wronly sb-posix:o-excl sb-posix:o-creat) #o600))) ;;;----------------------------- (defparameter *fh* (open path :direction :output :if-exists :append :if-does-not-exist :create)) #+sbcl (progn (defparameter *fh* (sb-posix:open path (logior sb-posix:o-wronly sb-posix:o-append sb-posix:o-creat))) (defparameter *fh* (sb-posix:open path (logior sb-posix:o-wronly sb-posix:o-append sb-posix:o-creat) #o600))) ;;;----------------------------- (defparameter *fh* (sb-posix:open path (logior sb-posix:o-wronly sb-posix:o-append))) ;;;----------------------------- (defparameter *fh* (open path :direction :io :if-exists :overwrite)) #+sbcl (defparameter *fh* (sb-posix:open path sb-posix:o-rdwr)) ;;;----------------------------- #+sbcl (progn (defparameter *fh* (sb-posix:open path (logior sb-posix:o-rdwr sb-posix:o-creat))) (defparameter *fh* (sb-posix:open path (logior sb-posix:o-rdwr sb-posix:o-creat) #o600))) ;;;----------------------------- #+sbcl (progn (defparameter *fh* (sb-posix:open path (logior sb-posix:o-rdwr sb-posix:o-excl sb-posix:o-creat))) (defparameter *fh* (sb-posix:open path (logior sb-posix:o-rdwr sb-posix:o-excl sb-posix:o-creat) #o600))) ;;;----------------------------- |
;;;----------------------------- ;; The machinations that the Perl example is doing is dealing with the ;; fact that Perl normally ignores leading whitespace in a filename. ;; This shouldn't be necessary in CL (since the filename doesn't also ;; contain the input mode, as it does in Perl), but the following ;; example illustrates how to do the same thing anyway. (setf *filename* (regex-replace "^(\\s)" *filename* "./$1")) ;; I'm not sure what the \0 being appended in the Perl example is for, ;; but SBCL, at least, doesn't seem to even allow NUL in a namestring ;; (filename), so it's not shown here. (defparameter *handle* (open *filename*)) ;;;----------------------------- #+sbcl (defparameter *handle* (sb-posix:open *filename* sb-posix:o-rdonly)) ;;;----------------------------- (defparameter *filename* (second *posix-argv*)) (defparameter *input* (open *filename*)) ;;;----------------------------- (defparameter *output* (open *filename* :direction :output)) ;;;----------------------------- #+sbcl (defparameter *output* (sb-posix:open *filename* (logior sb-posix:o-wronly sb-posix:o-trunc))) ;;;----------------------------- (setf *file* (regex-replace "^(\\s)" *file* "./$1")) (defparameter *output* (open *file* :direction :output)) ;;;----------------------------- |
;;;----------------------------- ;;; @@INCOMPLETE@@ ;;; @@INCOMPLETE@@ |
;;;----------------------------- ;; You should not normally do this in CL. However the example below ;; does roughly the same thing as the Perl and is a crude example of ;; how you can handle exceptions in CL. (handler-case (let ((file (open *path*))) ;; use FILE ) ;; Catch "all" exceptions (CONDITION is the base class of all ;; "exceptions" in CL). (condition (msg) (format *error-output* "~&Couldn't open ~A for reading : ~A~%" *path* msg))) ;;;----------------------------- |
;;;----------------------------- (defparameter *data* " Your data goes here ") (loop for line in (split #\Newline *data*) do (progn ;; process the line )) ;;;----------------------------- ;; The Perl example here would be the same as the above. ;;;----------------------------- ;; There's no equivalent to how DATA is used here. E.g., there's no ;; standard way to get the currently executing "script" file. ;;;----------------------------- |
;;;----------------------------- (loop for filehandle in *filehandles* ; *FILEHANDLES* is list of STREAM objects do (princ stuff-to-print filehandle)) ;;;----------------------------- ;;; @@INCOMPLETE@@ |