Skip to content

Instantly share code, notes, and snippets.

@alaa-alawi
Created May 21, 2012 16:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alaa-alawi/2763054 to your computer and use it in GitHub Desktop.
Save alaa-alawi/2763054 to your computer and use it in GitHub Desktop.
implementation comparision
;; original implementation
;; hunchentoot;utils.lisp
;;
(let ((counter 0))
(declare (ignorable counter))
(defun make-tmp-file-name (&optional (prefix "hunchentoot"))
"Generates a unique name for a temporary file. This function is
called from the RFC2388 library when a file is uploaded."
(let ((tmp-file-name
#+:allegro
(pathname (system:make-temp-file-name prefix *tmp-directory*))
#-:allegro
(loop for pathname = (make-pathname :name (format nil "~A-~A"
prefix (incf counter))
:type nil
:defaults *tmp-directory*)
unless (probe-file pathname)
return pathname)))
(push tmp-file-name *tmp-files*)
;; maybe call hook for file uploads
(when *file-upload-hook*
(funcall *file-upload-hook* tmp-file-name))
tmp-file-name)))
;; users are responsible for making sure *file-upload-hook* is called in their supplied implementation in *upload-filename-generator*
;;
;; make-tmp-file-name implementation is the same as the original one
(defun make-upload-filename ()
(let ((designator (cond
;; the old behaviour.
((null *upload-filename-generator*)
t)
;; the new behaviour.
((or (symbolp *upload-filename-generator*)
(functionp *upload-filename-generator*))
*upload-filename-generator*))))
designator))
;; we wrap the supplied one with our own lambda to ensure that *file-upload-hook* is called properly.
;;; make-tmp-file-name implementation is the same as the original one
(defun make-upload-filename ()
(let ((designator (cond
;; the old behaviour.
((null *upload-filename-generator*)
t)
;; the new behaviour.
((or (symbolp *upload-filename-generator*)
(functionp *upload-filename-generator*))
(lambda (&key field-name file-name content-type :allow-other-keys t)
(let ((filename (funcall *upload-filename-generator*
:field-name field-name
:file-name file-name
:content-type content-type
:allow-other-keys t)))
(when *file-upload-hook*
(funcall *file-upload-hook* filename))
filename))))))
designator))
@hanshuebner
Copy link

There is nothing wrong with v2 in principle. Minor comments:

The name "designator" is not needed.
The cond should be an etypecase

(etypecase upload-filename-generator
(null ....)
((or symbol function) ...)

The lambda should have (&rest args &key file-name &allow-other-keys) as lambda list and invoke upload-filename-generator with (apply upload-filename-generator args)

@alaa-alawi
Copy link
Author

Is there a reason to only include file-name and not the others (field-name and content-type)? or it is just for the example, and I should include them in the code? (I know that not writing them does not have effect on calling the function, but there presence help in the making the code clearer)

@alaa-alawi
Copy link
Author

(defun make-upload-filename ()
  (etypecase *upload-filename-generator* 
    ;; the old behaviour.
    (null t)
    ;; the new behaviour.
    ((or symbol function) 
     (lambda (&rest args &key field-name file-name content-type &allow-other-keys)
       (let ((filename (apply *upload-filename-generator* args)))
         (when *file-upload-hook*
           (funcall *file-upload-hook* filename))
         filename)))))

@hanshuebner
Copy link

hanshuebner commented May 21, 2012 via email

@hanshuebner
Copy link

Remove the &key arguments. The fact that upload-filename-generator accepts keyword arguments is completely irrelevant for this wrapper lambda. It wraps the invocation to invoke the hook function, and that is all that the code should express.

@alaa-alawi
Copy link
Author

(defun make-upload-filename ()
  (etypecase *upload-filename-generator* 
    ;; the old behaviour.
    (null t)
    ;; the new behaviour.
    ((or symbol function) 
     (lambda (&rest args)
       (let ((filename (apply *upload-filename-generator* args)))
         (when *file-upload-hook*
           (funcall *file-upload-hook* filename))
         filename)))))

@alaa-alawi
Copy link
Author

alaa-alawi commented May 21, 2012 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment