From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 15538 invoked by alias); 30 Dec 2012 19:21:12 -0000 Mailing-List: contact zsh-users-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Users List List-Post: List-Help: X-Seq: 17508 Received: (qmail 10929 invoked from network); 30 Dec 2012 19:21:09 -0000 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.2 Received-SPF: none (ns1.primenet.com.au: domain at closedmail.com does not designate permitted sender hosts) From: Bart Schaefer Message-id: <121230112044.ZM879@torch.brasslantern.com> Date: Sun, 30 Dec 2012 11:20:44 -0800 In-reply-to: Comments: In reply to Russell Harmon "Creating A Clean Environment For Autoloaded Functions" (Dec 30, 4:44am) References: X-Mailer: OpenZMail Classic (0.9.2 24April2005) To: zsh-users@zsh.org Subject: Re: Creating A Clean Environment For Autoloaded Functions MIME-version: 1.0 Content-type: text/plain; charset=us-ascii On Dec 30, 4:44am, Russell Harmon wrote: > > If I want to write a function which can be autoloaded, how can I > prevent functions defined outside of my function from being accessible > from within my function? For example, I have a function ls { gls "$@" > }, and I know of no way to prevent that function from leaking into the > definition of all the functions I've autoloaded which use ls. This amounts to asking how to violate a basic tenet of shell function behavior. They're supposed to act like commands that are always at the front of the search path, and the search path doesn't change based on the order in which every other command was added to it. The way you avoid this is to write every function that explicitly does not want this behavior so as to explicitly override it; for examply by using "command ls" instead of "ls". However, you could do something like this, assuming zsh/parameter is loaded: ls() { if (( $#funcstack > 1 )) then command ls "$@" else gls "$@" fi } This will prevent gls from being run inside any other function, although it won't bypass the ls wrapper function entirely. > Additionally, is it possible to zmodload a module which is > automatically unloaded from the environment after my function > completes _only if_ that module was not already loaded? There isn't a property of modules that supports this, but you can do it yourself explicitly with something like this: { zmodload -e zsh/mathfunc # for example local unload_mathfunc=$? zmodload zsh/mathfunc : do what you need to with math functions } always { (( unload_mathfunc )) && zmodload -u zsh/mathfunc } If the zsh/parameter module is not itself one of the ones you care about unloading in this way, you can be more generic: { zmodload zsh/parameter local -a existing_modules existing_modules=( ${(k)modules[(R)loaded]} ) : do whatever zmodloads you want ... } always { # Requires zsh 5.0, otherwise you need a loop zmodload -u ${(k)modules[(R)loaded]:|existing_modules} } I'm not sure that zmodload is clever enough to notice that inter-module dependencies have been satisfied by the list provided to -u and thus unload the modules in the correct order to be sure it succeeds, so a bit of tweaking to the above may be required for full generality.