Path: utzoo!telly!philmtl!uunet!tut.cis.ohio-state.edu!usenet.ins.cwru.edu!cwns1!chet From: chet@cwns1.CWRU.EDU (Chet Ramey) Newsgroups: gnu.bash.bug Subject: Re: bash bug report Message-ID: <1989Dec14.212828.5302@usenet.ins.cwru.edu> Date: 14 Dec 89 21:28:28 GMT References: <8912132157.AA04187@sbphy.Ucsb.EDU> Reply-To: chet@po.CWRU.Edu (Chet Ramey) Distribution: gnu Organization: Case Western Reserve Univ. Cleveland, Ohio, (USA) Lines: 143 In article <8912132157.AA04187@sbphy.Ucsb.EDU> bfox@sbphy.ai.mit.edu (Brian Fox) writes: > > Date: 13 Dec 89 17:28:36 GMT > From: mcsun!sunic!nuug!ifi!digre!anders@uunet.uu.net (Anders Ellefsrud) > References: <8912030428.AA01426@kailand.kai.com>, <3749@convex.UUCP> > Sender: bug-bash-request@prep.ai.mit.edu > > > >I've been told by devout ksh users that it's missing autoload functions. > >Please send documentation on "autoload functions". When you declare a function `autoload', it is marked as `undefined', and its definition is deferred until its first use. When such a function is referenced for the first time, a search is made of the `FPATH', a colon-separated list of directories just like $PATH, for a file whose name is the same as the function. If found, the file is then read in as if it had been the argument to a `.' command, and the function is executed. This is, I guess, how you get function libraries for doing shell programming. `autoload' is really a predefined alias for `typeset -fu' Here are two functions that will do pretty much the same thing for bash, with only a couple of differences. You need two fixes for bash to make this work `right': the fix for "$@" and a fix to stop the `.' command from blowing away the dollar variables unconditionally (ksh assigns extra arguments to `.' to the dollar variables, but leaves them alone if there are no extra args). `autoload' does the whole deal: handle multiple arguments, parse $FPATH, and so on. It calls `aload', which is a descendent of Bill Trost's `autoload' function, for each argument that it finds. An autoloaded function will be loaded from its source file on first reference, its definition will be replaced by the one in the source file, then the new definition will be run. This is about the best you can do without source support. Chet Ramey # # An almost ksh-compatible `autoload'. A function declared as `autoload' will # be read in from a file the same name as the function found by searching the # $FPATH (which works the same as $PATH), then that definition will be run. # # To do this without source support, we define a dummy function that, when # executed, will load the file (thereby re-defining the function), then # execute that newly-redefined function with the original arguments. # # It's not identical to ksh because ksh apparently does lazy evaluation # and looks for the file to load from only when the function is referenced. # This one requires that the file exist when the function is declared as # `autoload'. # # usage: autoload func [func...] # # The first cut of this was by Bill Trost, trost@reed.bitnet # # Chet Ramey # chet@ins.CWRU.Edu # # Declare a function ($1) to be autoloaded from a file ($2) when it is first # called. This defines a `temporary' function that will `.' the file # containg the real function definition, then execute that new definition with # the arguments given to this `fake' function. The autoload function defined # by the file and the file itself *must* be named identically. # aload() { echo $1 \(\) \{ . $2 \; $1 \"\$\@\" \} > /tmp/au.$$ . /tmp/au.$$ rm /tmp/au.$$ } # # Search $FPATH for a file the same name as the function given as $1, and # autoload the function from that file. There is no default $FPATH. # autoload() { # # save the list of functions; we're going to blow away the arguments # in a second # local args="$*" if [ $# -eq 0 ] ; then echo "usage: autoload function [function...]" return 1 fi # # If there is no $FPATH, there is no work to be done # if [ -z "$FPATH" ] ; then echo autoload: FPATH not set return 1 fi # # This treats FPATH exactly like PATH: a null field anywhere in the # FPATH is treated the same as the current directory. # # The path splitting command is taken from Kernighan and Pike # fp=$(echo $FPATH | sed 's/^:/.:/ s/::/:.:/g s/:$/:./ s/:/ /g') for FUNC in $args ; do # # We're blowing away the arguments to autoload here... # set $fp while [ $# -ne 0 ] ; do if [ -f $1/$FUNC ] ; then break # found it! fi shift done if [ $# -eq 0 ] ; then echo "$FUNC: autoload function not found" continue fi # echo auto-loading $FUNC from $1/$FUNC aload $FUNC $1/$FUNC done return 0 } -- Chet Ramey Network Services Group "Where's my froggie?" Case Western Reserve University chet@ins.CWRU.Edu