* Tag functions with shell options? @ 1996-07-02 12:05 Anthony Heading 1996-07-02 13:36 ` Zefram 1996-07-02 15:37 ` Peter Stephenson 0 siblings, 2 replies; 10+ messages in thread From: Anthony Heading @ 1996-07-02 12:05 UTC (permalink / raw) To: zsh-workers I've hit a small shell-based problem, and I wonder if it's a common one... My dearly beloved employers, or rather their technology guys, have come up with a Unix application load/unload scheme. And it works in a reasonably sensible way, by defining shell functions which grub around in config files and then set shell and environment variables appropriately. The trouble is that these functions rely on sh-style word splitting, which I don't have (or want) turned on by default. So I think I need some way of marking these functions to be interpreted with SH_WORD_SPLIT turned on locally. Or have I missed something simple? Anthony ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Tag functions with shell options? 1996-07-02 12:05 Tag functions with shell options? Anthony Heading @ 1996-07-02 13:36 ` Zefram 1996-07-02 14:12 ` Anthony Heading 1996-07-02 15:37 ` Peter Stephenson 1 sibling, 1 reply; 10+ messages in thread From: Zefram @ 1996-07-02 13:36 UTC (permalink / raw) To: Anthony Heading; +Cc: zsh-workers >So I think I need some way of marking these functions to be interpreted with >SH_WORD_SPLIT turned on locally. Or have I missed something simple? awkward_func () { setopt local_options sh_word_split ... } This will set SH_WORD_SPLIT for the duration of the function, restoring the state when it returns. -zefram ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Tag functions with shell options? 1996-07-02 13:36 ` Zefram @ 1996-07-02 14:12 ` Anthony Heading 1996-07-02 15:17 ` Zefram 0 siblings, 1 reply; 10+ messages in thread From: Anthony Heading @ 1996-07-02 14:12 UTC (permalink / raw) To: Zefram; +Cc: zsh-workers Zefram wrote: > >So I think I need some way of marking these functions to be interpreted with > >SH_WORD_SPLIT turned on locally. Or have I missed something simple? > > awkward_func () { > setopt local_options sh_word_split > ... > } > > This will set SH_WORD_SPLIT for the duration of the function, restoring > the state when it returns. Thanks for the response. The trouble is that I can't alter awkward_func. Effectively I have a library of Bourne shell functions which I'd like to use from zsh, without knowing about their internals, and I can't see how to do it. Anthony ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Tag functions with shell options? 1996-07-02 14:12 ` Anthony Heading @ 1996-07-02 15:17 ` Zefram 0 siblings, 0 replies; 10+ messages in thread From: Zefram @ 1996-07-02 15:17 UTC (permalink / raw) To: Anthony Heading; +Cc: A.Main, zsh-workers >Thanks for the response. The trouble is that I can't alter awkward_func. Effectively >I have a library of Bourne shell functions which I'd like to use from zsh, without >knowing about their internals, and I can't see how to do it. You could wrap the Bourne shell functions in zsh functions that do the LOCAL_OPTIONS thing. -zefram ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Tag functions with shell options? 1996-07-02 12:05 Tag functions with shell options? Anthony Heading 1996-07-02 13:36 ` Zefram @ 1996-07-02 15:37 ` Peter Stephenson 1996-07-02 16:57 ` Anthony Heading 1 sibling, 1 reply; 10+ messages in thread From: Peter Stephenson @ 1996-07-02 15:37 UTC (permalink / raw) To: Zsh hackers list aheading@jpmorgan.com wrote: > So I think I need some way of marking these functions to be interpreted with > SH_WORD_SPLIT turned on locally. Or have I missed something simple? This is definitely a weak point in compatibility. Perhaps in a future version we do want special ways of doing things like this. Some time ago, people were suggesting having hooks you could call when a function was called etc.; that would do the trick too. However, for the time being... I take it the problem is within the function, i.e. you don't actually have problems on the command line yourself? In that case it would be outside the scope of the function. Another problem arises if the functions get defined at arbitrary points during execution (err, like the sws_locate function below, in fact). In that case you're basically stuck without at the least a smart script to convert all functions defined inside in the appropriate manner. If they are playing fair, however, try this function. You need to call it with the names of all the functions you want to have run with sh_word_split turned on. They can be either already in memory or autoloadable: in the latter case, it assumes they are ksh-like autoloadable functions, i.e. the entire function definition is there including the `function foo { ... } bit.' It relies on the fact that `functions foo' returns an accurate representation of foo. I've been trying to ensure this over the years, but there almost certainly some things we've all missed. sws_fn () { # Convert a sh or ksh function to run under zsh by the addition of # some set of options. The function may already be defined, or be in # some autoload directory. # This is the text we\'d like added at the top of the function. local optline="setopt shwordsplit localoptions" local func body dir fnfile sws_locate() { # Find an autoload file. local dir for dir in $fpath; do if [[ -f $dir/$1 ]]; then fnfile=$dir/$1 return 0 fi done return 1 } for func; do if [[ "$(functions $func | head -1)" = *undefined* ]] && sws_locate $func; then # We're assuming these are ksh-like autoload functions, # i.e. they contain the full function include definition lines. . $fnfile fi body="$(functions $func 2>&1 | sed -e 1d -e '$d')" [[ -z $body ]] && print "No such function: $func" >&2 && continue eval "function $func { $optline $body }" done } -- Peter Stephenson <pws@ifh.de> Tel: +49 33762 77366 WWW: http://www.ifh.de/~pws/ Fax: +49 33762 77330 Deutches Electronen-Synchrotron --- Institut fuer Hochenergiephysik Zeuthen DESY-IfH, 15735 Zeuthen, Germany. ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Tag functions with shell options? 1996-07-02 15:37 ` Peter Stephenson @ 1996-07-02 16:57 ` Anthony Heading 1996-07-02 19:07 ` Bart Schaefer 0 siblings, 1 reply; 10+ messages in thread From: Anthony Heading @ 1996-07-02 16:57 UTC (permalink / raw) To: Peter Stephenson; +Cc: zsh-workers Peter wrote: > If they are playing fair, however, try this function. Thanks. That's a bit cleaner than the hack I was resorting to - viz . <( sed /blaa/ foo.sh) trying to edit the functions on the way in. On a longer term, perhaps lexical closures are possibility? It would be pleasingly complicated. Anthony ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Tag functions with shell options? 1996-07-02 16:57 ` Anthony Heading @ 1996-07-02 19:07 ` Bart Schaefer 1996-07-02 19:53 ` Anthony Heading 0 siblings, 1 reply; 10+ messages in thread From: Bart Schaefer @ 1996-07-02 19:07 UTC (permalink / raw) To: Anthony Heading, Peter Stephenson, Zefram, zsh-workers On Jul 2, 5:37pm, Peter Stephenson wrote: } Subject: Re: Tag functions with shell options? } } aheading@jpmorgan.com wrote: } > So I think I need some way of marking these functions to be interpreted } > with SH_WORD_SPLIT turned on locally. Or have I missed something simple? } } This is definitely a weak point in compatibility. Perhaps in a future } version we do want special ways of doing things like this. Some time } ago, people were suggesting having hooks you could call when a } function was called etc.; that would do the trick too. I like the hook idea, but I think something simpler would be sufficient in this case. On Jul 2, 4:17pm, Zefram wrote: } You could wrap the Bourne shell functions in zsh functions that do the } LOCAL_OPTIONS thing. That's how I'd approach it, and that's mostly what Peter's sws_fn does. I've been using this trick in my .zshrc for years: if typeset -f precmd >& /dev/null then let n=1 while typeset -f x${n}precmd >& /dev/null; do let n++; done eval x${n}"`typeset -f precmd`" if [[ "$TERM" = screen ]] then eval "precmd() { title ; x${n}precmd }" else eval "precmd() { TMOUT=600 ; title ; x${n}precmd }" fi fi What that does is rename precmd to a new name that doesn't exist, and then creates a new precmd which sets the title bar and calls the new name. Unfortunately, that doesn't work on autoloaded functions, which is what most of the work in sws_fn is fixing. What would be nice is if one of the zsh builtins permitted forcing load of an autoload function without running the function, and if a builtin permtitted a function's name to be changed without redefining it. [Back to PWS again:] } Another problem arises if the functions get defined at arbitrary } points during execution (err, like the sws_locate function below, in } fact). In that case you're basically stuck without at the least a } smart script to convert all functions defined inside in the } appropriate manner. Right; it doesn't seem that Anthony has given us enough context. Do the functions get defined and then executed all within /etc/profile, for example? Or do they act as wrappers around actual applications, so they don't run until you execute them "manually"? (Sounds like the latter, but ...) Are you explicitly sourcing the script that defines those functions, or are they in a startup script that zsh reads automatically? If you know the names of all the functions that need to be wrapped, it seems to me that a much simpler implementation of sws_fn is: sws_fn () { # \\${1} below is in case of multiple calls to `sws_fn foo` # for the same 'foo', to be sure an alias isn't referenced. eval "SWS_${1} () { setopt localoptions shwordsplit; \\${1} }" alias ${1}=SWS_${1} } The only drawback to this is that other functions that may already have been defined won't see the alias -- but presumably those functions will themselves be given the sws_fn treatment, so it's moot. BTW, does it bother anyone else that, for textually-identical definitions of `foo': foo() { bar } alias bar=baz Is not equivalent to: autoload foo alias bar=baz ?? -- Bart Schaefer Brass Lantern Enterprises http://www.well.com/user/barts http://www.nbn.com/people/lantern New male in /home/schaefer: >N 2 Justin William Schaefer Sat May 11 03:43 53/4040 "Happy Birthday" ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Tag functions with shell options? 1996-07-02 19:07 ` Bart Schaefer @ 1996-07-02 19:53 ` Anthony Heading 1996-07-02 21:31 ` Bart Schaefer 0 siblings, 1 reply; 10+ messages in thread From: Anthony Heading @ 1996-07-02 19:53 UTC (permalink / raw) To: schaefer; +Cc: aheading, pws, A.Main, zsh-workers > Right; it doesn't seem that Anthony has given us enough context. Do > the functions get defined and then executed all within /etc/profile, > for example? Or do they act as wrappers around actual applications, > so they don't run until you execute them "manually"? (Sounds like the > latter, but ...) Yes, the latter. The lack of context was sort-of deliberate, since I suspected any interest would be in the wider picture, rather than my particular petty problems. It seemed simply an example of something it would be nice to support elegantly. > it seems to me that a much simpler implementation of sws_fn is: [wrapping the function, and then aliasing the wrapper to the original] > The only drawback to this is that other functions that may already have > been defined won't see the alias -- but presumably those functions will > themselves be given the sws_fn treatment, so it's moot. Hmm. Don't understand the first point, but I'll experiment. Thanks Anthony ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Tag functions with shell options? 1996-07-02 19:53 ` Anthony Heading @ 1996-07-02 21:31 ` Bart Schaefer 1996-07-02 22:27 ` Anthony Heading 0 siblings, 1 reply; 10+ messages in thread From: Bart Schaefer @ 1996-07-02 21:31 UTC (permalink / raw) To: Anthony Heading; +Cc: zsh-workers On Jul 2, 8:53pm, Anthony Heading wrote: } Subject: Re: Tag functions with shell options? } } The lack of context was sort-of deliberate, since I } suspected any interest would be in the wider picture, rather than my } particular petty problems. It seemed simply an example of something } it would be nice to support elegantly. This introduces a whole class of problems, which is most obvious in the case when you *do not* know the names of the functions that should have their local options (or whatever) changed. In that case you almost end up needing something like Perl's "package", so that you can do e.g.: package admin . /etc/profile for f in $(whence -FP admin) do typeset -fo ${f}=(shwordsplit globassign bsdecho nobgnice);; done Where I'm assuming a slew of new features: 1. `package foo' groups all functions, aliases, etc. in the package named `foo' until the next `package' is executed 2. `whence -F' lists the names (but NOT definitions) of functions [Aside: Why doesn't `typeset +f' do that already?] 3. `whence -P foo' lists from the package `foo' 4. `typeset -o' is equivalent to `setopt' (and `+o' to `unsetopt') 5. `typeset -fo foo=(options...)' sets local options for `foo', as if `foo' began with `setopt localoptions options...' 6. Zoltan's (or was it Zefram's?) change to make `setopt nofoo' be equivalent to `unsetopt foo' } > it seems to me that a much simpler implementation of sws_fn is: } [wrapping the function, and then aliasing the wrapper to the original] } } > The only drawback to this is that other functions that may already have } > been defined won't see the alias -- but presumably those functions will } > themselves be given the sws_fn treatment, so it's moot. } } Hmm. Don't understand the first point, but I'll experiment. Example: yfn () { echo Y } zfn () { echo Z } xfn1 () { yfn } alias yfn=zfn xfn2 () { yfn } Now: zsh% xfn1 Y zsh% xfn2 Z Because the alias for yfn was introduced *after* xfn1 was defined, xfn1 still references the "real" yfn, rather than the alias. The presumption is that if you're going to use sws_fn yfn Then you are also going to use sws_fn xfn1 sws_fn xfn2 So that it doesn't matter what "yfn" means inside of xfn*. -- Bart Schaefer Brass Lantern Enterprises http://www.well.com/user/barts http://www.nbn.com/people/lantern New male in /home/schaefer: >N 2 Justin William Schaefer Sat May 11 03:43 53/4040 "Happy Birthday" ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: Tag functions with shell options? 1996-07-02 21:31 ` Bart Schaefer @ 1996-07-02 22:27 ` Anthony Heading 0 siblings, 0 replies; 10+ messages in thread From: Anthony Heading @ 1996-07-02 22:27 UTC (permalink / raw) To: schaefer; +Cc: aheading, zsh-workers Bart wrote: > > } The lack of context was sort-of deliberate, since I > } suspected any interest would be in the wider picture, rather than my > } particular petty problems. It seemed simply an example of something > } it would be nice to support elegantly. > > This introduces a whole class of problems, which is most obvious in the > case when you *do not* know the names of the functions that should have > their local options (or whatever) changed. In that case you almost end > up needing something like Perl's "package". Right. I guess this is like what I would have thought of doing as a sort of closure. So a function, when defined, would snapshot its option-environment. function setup() { setopt local_options closure_options sh_word_split . /someone/elses/setup/file.sh } > Because the alias for yfn was introduced *after* xfn1 was defined, xfn1 > still references the "real" yfn, rather than the alias. The presumption > is that if you're going to use OK. As if aliases are resolved at parse-time. Or something. Perhaps they are. I should RTFS. But I understand now. Thank-you all. A ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~1996-07-02 22:35 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 1996-07-02 12:05 Tag functions with shell options? Anthony Heading 1996-07-02 13:36 ` Zefram 1996-07-02 14:12 ` Anthony Heading 1996-07-02 15:17 ` Zefram 1996-07-02 15:37 ` Peter Stephenson 1996-07-02 16:57 ` Anthony Heading 1996-07-02 19:07 ` Bart Schaefer 1996-07-02 19:53 ` Anthony Heading 1996-07-02 21:31 ` Bart Schaefer 1996-07-02 22:27 ` Anthony Heading
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).