Arc Forumnew | comments | leaders | submitlogin
What's the purpose of "hook"?
2 points by thaddeus 5377 days ago | 2 comments
It appears defhook simply creates a function that gets registered in hooks* and becomes called by hook. I am wondering how people are using this? Isn't calling a named function just as easy as using hook? There's obviously some practical application that I am just not seeing....


3 points by fallintothis 5377 days ago | link

You could call a named function, but hooks are only called if they're defined, since hook is written as

  (def hook (name . args)
    (aif (hooks* name) (apply it args)))
They're just a convenience. You can specify a place where, if there is a function to call, you call it. You "hook" into certain pieces of code. news.arc uses them all over the place, like in the last line of

  (def edit-page (user i)
    (let here (edit-url i)
      (shortpage user nil nil "Edit" here
        (tab (display-item nil i user here)
             (display-item-text i user))
        (br2)
        (vars-form user
                   ((fieldfn* i!type) user i)
                   (fn (name val) 
                     (unless (ignore-edit user i name val)
                       (when (and (is name 'dead) val (no i!dead))
                         (log-kill i user))
                       (= (i name) val)))
                   (fn () (if (admin user) (pushnew 'locked i!keys))
                          (save-item i)
                          (metastory&adjust-rank i)
                          (wipe (comment-cache* i!id))
                          (edit-page user i)))
        (hook 'edit user i))))
I've not read news.arc thoroughly, so I don't know if this example actually works 100%, but humor me: Say at one point you need to diagnose a problem with edit-page, so you (defhook edit ...) to log the user on each call. After finding the problem, you need to change how edits work, so you (defhook edit ...) again to render an alert message that lets users know how editing has changed. But you don't want that message up forever, so after a week you (defhook edit (user i) nil).

-----

1 point by thaddeus 5377 days ago | link

Ahhh... Thank you - I get it. I can totally see using hook for logging purposes and I can imagine a bunch of other uses for it too...

example:

(= mydata (fromjson "{\"first\":\"Edgar\",\"last\":\"Poe\",\"age\":\"23\",\"dob\":\"Jan 19 1809\"}"))

(= datatypes (obj "first" 'text "last" 'text "age" 'integer "dob" 'date))

(= mydatabase (table))

  arc> mydata
  #hash(("last" . "Poe") ("first" . "Edgar") ("age" . "23") ("dob" . "Jan 19 1809"))

  (defhook integer (val)
    (coerce val 'int))

  (defhook date (val)
    (upcase val))

  (def storedata (mydb typedb)
   (each field (keys mydb)
     (fill-table mydatabase 
        (list field (aif (hook typedb.field mydb.field) it mydb.field))))
    mydatabase)

  arc> (storedata mydata datatypes)
  #hash(("last" . "Poe") ("age" . 23) ("first" . "Edgar") ("dob" . "JAN 19 1809"))
It should have clicked in when I saw aif, but it didn't.

-----