zsh-workers
 help / color / mirror / code / Atom feed
From: "Bart Schaefer" <schaefer@brasslantern.com>
To: Sven Wischnowsky <wischnow@informatik.hu-berlin.de>
Cc: zsh-workers@math.gatech.edu
Subject: Re: wrapper functions in modules
Date: Fri, 11 Dec 1998 05:18:22 -0800	[thread overview]
Message-ID: <981211051822.ZM20223@candle.brasslantern.com> (raw)
In-Reply-To: <199812091444.PAA02328@beta.informatik.hu-berlin.de>

On Dec 9,  3:44pm, Sven Wischnowsky wrote:
} Subject: PATCH: wrapper functions in modules
}
} The patch below allows modules to register functions that are to be
} executed before and after a function is called.

I understand why you did this, but it's a potential pit of vipers,
especially given the linear list traversal used to call the wrappers.

My first concern is with ordering dependencies among modules.  The
module dependency mechanism can be used to assure that module X's
"before" wrapper is in the linked list ahead of module Y's, but what
about the "after" wrappers?  Surely they should be called in opposite
order from the "before" wrappers, so that Y can unwind its state before
X yanks some vital data out from under it?

Also, the additional patches to delay module unloading introduce other
problems.  Suppose I have a module that redefines the "echo" builtin.
Consider:

	function call-the-wrong-echo {
	    zmodload my_echo
	    echo "This should be my own echo."
	    zmodload -u my_echo
	    echo "This ought to be builtin echo."
	}

You have to split unloading into two parts, one that takes away the
"user interface" and another that finally disengages the C functions.

That probably further introduces the need to split the module's own
cleanup function into those same two parts, because "zmodload -u" has
to fail at the moment that it's executed if it's going to fail at all,
not some long while later when the shell-function call-stack unwinds.

And then we're back to the dependency problems again -- when you're done
calling all the wrapper functions, you have to unload the modules IN THE
ORDER THAT THE zmodload -u COMMANDS WERE EXECUTED, not in whatever order
the modules happen to have been added (or not) to the wrappers list.  It's
not good enough to delay the unloading only of modules that have wrappers,
you also have to delay unloading all the way along the module dependency
chains.

Even with all that fixed, there's the problem of shell functions calling
other shell functions.  Here's the most glaring example:

	function call-too-many-after-wrappers {
	    if (($1 == 10))
	    then
	    	zmodload example
	    else
		call-too-many-after-wrappers $[$1+1]
	    fi
	}

Even in nonrecursive cases, every module's wrapper has to maintain its
own idea of the state of the call stack to "do the right thing" with
respect to nested shell function scopes.

Worse, this interacts with the staged-unload problem, because once you
have called "zmodload -u", any further calls to the "before" wrappers
ought to become no-ops; but you have to be sure the "after" wrappers
still get called at exactly the scopes where the "before" wrappers were
active.

You can fix or reduce some of these problems by:
1.  Make the list of "after" wrappers to be called a part of the
    doshfunc() stack frame, rather than always using the global list.
2.  Build that list by pushing wrappers on the front as you loop over
    the "before" wrappers, to get the reversed call sequence.
3.  Pass a "call stack depth" parameter or similar identifier to the
    before/after wrappers, to simplify the tests they must do.  (Even
    better, pass a pointer to some kind of scope structure that has
    the stack depth as a member.)

Nevertheless, this is so tangled that I'm sure I haven't yet listed all
the possible bad interactions.  We should think hard about whether there
is some other way to deal with the problems the wrappers are intended to
solve.

} This is completely hidden from the user so there is no documentation

There ought to be *developer* documentation for it, e.g., in the file
Util/zsh-development-guide or where other module developer documentation
lives (which is rather scatterbrained at the moment).  The example
module is totally insufficient to give an understanding of this kind of
complexity.

-- 
Bart Schaefer                                 Brass Lantern Enterprises
http://www.well.com/user/barts              http://www.brasslantern.com


  reply	other threads:[~1998-12-11 13:28 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1998-12-09 14:44 PATCH: " Sven Wischnowsky
1998-12-11 13:18 ` Bart Schaefer [this message]
1998-12-11 14:16 Sven Wischnowsky
1998-12-11 17:40 ` Bart Schaefer
1998-12-14 10:11 Sven Wischnowsky
1998-12-14 18:42 ` Bart Schaefer
1998-12-15 12:03 Sven Wischnowsky
1998-12-15 17:05 ` Bart Schaefer
1998-12-16  8:05 Sven Wischnowsky
1998-12-16  9:50 ` Bart Schaefer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=981211051822.ZM20223@candle.brasslantern.com \
    --to=schaefer@brasslantern.com \
    --cc=wischnow@informatik.hu-berlin.de \
    --cc=zsh-workers@math.gatech.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).