From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: William Case Newsgroups: gmane.emacs.help Subject: RE: What do 'hooks' do and how do they do it? Date: Sat, 01 Aug 2009 22:44:40 +0000 Message-ID: <1249166680.2246.52.camel@CASE> References: <1249147043.2246.18.camel@CASE> <86iqh7ct32.wl%djcb@djcbsoftware.nl> <1249159408.2246.35.camel@CASE> <92BB348CF47244E5A4BAB82CA4021A7A@us.oracle.com> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain Content-Transfer-Encoding: 7bit X-Trace: ger.gmane.org 1249166779 3010 80.91.229.12 (1 Aug 2009 22:46:19 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Sat, 1 Aug 2009 22:46:19 +0000 (UTC) Cc: 'Emacs Help List' , djcb@djcbsoftware.nl To: Drew Adams Original-X-From: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Sun Aug 02 00:46:12 2009 Return-path: Envelope-to: geh-help-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([199.232.76.165]) by lo.gmane.org with esmtp (Exim 4.50) id 1MXNL8-0005I9-DU for geh-help-gnu-emacs@m.gmane.org; Sun, 02 Aug 2009 00:46:10 +0200 Original-Received: from localhost ([127.0.0.1]:58805 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MXNL7-0007eL-TR for geh-help-gnu-emacs@m.gmane.org; Sat, 01 Aug 2009 18:46:09 -0400 Original-Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MXNKj-0007eD-6Q for help-gnu-emacs@gnu.org; Sat, 01 Aug 2009 18:45:45 -0400 Original-Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MXNKe-0007cf-FC for help-gnu-emacs@gnu.org; Sat, 01 Aug 2009 18:45:44 -0400 Original-Received: from [199.232.76.173] (port=52612 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MXNKe-0007cc-9C for help-gnu-emacs@gnu.org; Sat, 01 Aug 2009 18:45:40 -0400 Original-Received: from smtp128.rog.mail.re2.yahoo.com ([206.190.53.33]:23161) by monty-python.gnu.org with smtp (Exim 4.60) (envelope-from ) id 1MXNKd-0002Rk-TR for help-gnu-emacs@gnu.org; Sat, 01 Aug 2009 18:45:40 -0400 Original-Received: (qmail 70084 invoked from network); 1 Aug 2009 22:45:39 -0000 DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=s1024; d=rogers.com; h=Received:X-YMail-OSG:X-Yahoo-Newman-Property:Subject:From:To:Cc:In-Reply-To:References:Content-Type:Date:Message-Id:Mime-Version:X-Mailer:Content-Transfer-Encoding; b=1zkF0CsfUSD2UwRskkIoKxQ07kWPddiL+7bs4E44QLqOss9tiL3aE/AA//nMLrhFbr8v8fkN+s2k5+vd7pC0m63DphNceKILx2ZHBKSMjPNZxki04JJzUNIfCjpXQJF+Q9EX9nIGu5wQBi7kvGhEcU33kc3wOsY//T4e9245qUk= ; Original-Received: from unknown (HELO ?192.168.1.3?) (billlinux@99.245.242.191 with plain) by smtp128.rog.mail.re2.yahoo.com with SMTP; 1 Aug 2009 22:45:39 -0000 X-YMail-OSG: cQUFcIQVM1l5IvIhOrvJb.YhBtkE40wswNoQLqWxHfavNlGvBlvJnegQSl7fWdRNmA-- X-Yahoo-Newman-Property: ymail-3 In-Reply-To: <92BB348CF47244E5A4BAB82CA4021A7A@us.oracle.com> X-Mailer: Evolution 2.26.3 (2.26.3-1.fc11) X-detected-operating-system: by monty-python.gnu.org: FreeBSD 4.7-5.2 (or MacOS X 10.2-10.4) (2) X-BeenThere: help-gnu-emacs@gnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Users list for the GNU Emacs text editor List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Original-Sender: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Errors-To: help-gnu-emacs-bounces+geh-help-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.help:66634 Archived-At: Sorry Drew; I wish I had calibrated my response to Dirk a bit better. On Sat, 2009-08-01 at 15:05 -0700, Drew Adams wrote: > > > I think Drew Adams gave a very clear answer about the Emacs > > > implementation, > > > > Yes he did. However, I tried to point out in my original post that I > > was aware of how to implement a 'hook' in emacs. > > Well, I did not explain how to implement a hook. I tried to explain what a hook > is: "a way to allow easy code extension at predefined places". > > I explained that when a hook is run in Emacs, the calling code just calls a > function (e.g. `run-hooks') that obtains the functions to invoke from a > variable's value. That's what a hook _is_, for Emacs; that's not how to > implement a hook. > On rereading your first post, the answer I wanted was, in fact, there. "A typical example is the code for a major mode, such as `emacs-lisp-mode'. The last thing such code does, when you turn on the mode, is to call `run-mode-hooks' to run the hook provided specifically for that mode, e.g. `emacs-lisp-mode-hook'. That is, it tries to invoke each of the functions on the list `emacs-lisp-mode-hook', in turn. If there are no functions on the hook, then nothing is done." > The general point is that (a) the call (when, why, etc.) is predefined, but (b) > what to call is determined dynamically (from the value of a variable, in the > case of Emacs). > > In particular, in Emacs, hooking has _nothing to do with events_. Invocation of > a hook function in Emacs is _not_ event-driven. > > > > but let me add that the concept of a 'hook' is simply a > > > programming technique: the ability to set some function > > > to be run whenever a particular event happens. > > Nope. (Unless the code that runs the hook variable happens to examine events to > determine whether to call `run-hooks'.) The event, so to speak, is turning on the mode. > > The call to invoke the hook functions is static. The functions to invoke are > determined dynamically by the value of a variable. The hook is the static part; > what's hooked is the dynamic part - think of hooking a fish, if you like. > > > I was curious about the programming technique that was used -- or more > > specifically -- how the hook function was setup so that the hook > > automagically responded to a program's hook event. > > There is nothing automagical here, and there is no hook event. Yes, I have tended to over use the term automagical since I first discovered the word. Almost always I use it in reference to correcting my understanding of things that seem automagical. To me, the automagical has no place in computing. > > > > The concept is in use in many places (such as SE-Linux), > > > but how it's implemented is quite different. In Emacs-Lisp, > > > the hooks are simply Lisp functions to be called -- no kernel > > > involved (well...). > > No. The "hooks" are the hook variables plus the calls to `run-hooks' that use > those variables, both of which are essentially static code. The values of the > hook variables are dynamic, and they determine which functions (the "hook > functions") get called. The functions called by the hooks are not the hooks; the > variables are the hooks. > > More generally, a "hook" is a predefined call to something to be determined > outside the static calling code. It is, well, a "hook" on which you can hang any > code you want executed. > > Hooks are static things; dynamic things are hung on the hooks. Think coat hooks > (stable, static) and coats that might be hung there (movable, dynamic, > changeable set). > > The hanging typically takes place at a different time from the definition of the > code that has the hook (the building of the coat rack). That's the point: > decouple where to do something from what actually gets done there. Those are > determined at different times: code writing vs runtime. > > Connecting (a) the actual functions to be called to (b) the hook that is made > available for calling them is, in effect, a form of dynamic or late binding. In > the case of Emacs, this is simply the binding of a variable to its value. > > This is akin to (funcall foo): the (functional) value of variable `foo' is > obtained at runtime, and it is called as a function. (funcall foo) is a kind of > "hook", on which is hung the value of `foo' at runtime. (But in Emacs we > generally reserve "hook" for a hook variable. Nevertheless, the overall concept > here is the same.) > > Note that in environments that are much less dynamic than Emacs and Lisp, hooks > can have greater importance: they are sometimes the _only_ effective way for > user code to be plugged into the main (binary) code. > > In the early days, giving users a way to branch their own calls into the main > code was sometimes called a "user exit". (A hook that was hidden was sometimes > called a "back door".) "User exit" pretty much sums up this claustrophobic state > of affairs: it was the only way to escape from the program to do something extra > or different. > I will keep the entirety of this reponse, in my personal emacs explanations file. > > > See: http://en.wikipedia.org/wiki/Hooking > > > > The wikipedia site you suggest above covers just about everything I > > wanted to know. I don't know how I missed it. > > Most of that page does not particularly apply to Emacs hooks, I'm afraid. The > general idea applies, but most of the hook mechanisms described on that page > have little relation to Emacs hooks. > OK. I'll keep that in mind. > What is most helpful on that page wrt Emacs hooks are the two sentences that > constitute the (entire) section "Emacs": > > "Hooks are an important mechanism for customization of Emacs. > A hook is a Lisp variable which holds a list of functions, > to be called on some well-defined occasion. (This is called > running the hook.)" > > The "well-defined occasion" and the hook variable together constitute the > stable, "hook" part. The functions on the list at any given time are the > dynamic, "hung" part. > > The best explanation of Emacs hooks and hooking remains the Emacs doc (which is > why I pointed you to it, and Wikipedia does likewise).HTH. All that I can say in my own defence, is that I had somewhat of a misconception of what hooks were and therefore I DID have good reason to ask further what hooks were. -- Regards Bill Fedora 11, Gnome 2.26.3 Evo.2.26.3, Emacs 22.3.1