zsh-workers
 help / color / mirror / code / Atom feed
* autoload -X inside an anonymous function
@ 2012-09-18  2:12 Oliver Kiddle
  2012-09-18 16:58 ` Bart Schaefer
  0 siblings, 1 reply; 12+ messages in thread
From: Oliver Kiddle @ 2012-09-18  2:12 UTC (permalink / raw)
  To: Zsh workers

While altering some autoloaded functions, it occurred to me to check what
would happen if you run autoload -X from inside an anonymous function.

The error message is not really what you would expect:
(eval):1: parse error near `"$@"'
Furthermore, running:
  which '(anon)'
shows that I also now have a named function named (anon).

The reason for the (eval) error message is that bin_eval is called to
run the function. This looks a bit of a hack with "$@" being passed as
an argument but also has other effects; most notable is another round
of alias expansion but you also get '(eval)' in $funcstack.

While looking at that relevant bits of code, I also wonder whether
the second call to eval_autoload is reachable code: no builtin using
bin_functions allows both the -m and -X options.

Trying to think of uses for an explicitly defined call to autoload -X,
it seems a pity you can't make it autoload a function from a differently
named file, either by first assigning to ARGV0 or passing a parameter
to autoload -X.

Oliver


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: autoload -X inside an anonymous function
  2012-09-18  2:12 autoload -X inside an anonymous function Oliver Kiddle
@ 2012-09-18 16:58 ` Bart Schaefer
  2012-09-19  0:35   ` Bart Schaefer
  2012-09-19  2:28   ` Oliver Kiddle
  0 siblings, 2 replies; 12+ messages in thread
From: Bart Schaefer @ 2012-09-18 16:58 UTC (permalink / raw)
  To: Zsh workers

On Sep 18,  4:12am, Oliver Kiddle wrote:
}
} The error message is not really what you would expect:
} (eval):1: parse error near `"$@"'

Hm.  The odd bit is that it got that far.  I would have expected it
to fail because there [presumably] is no file named '(anon)' in your
$fpath.  However, looking at the code again ...

} Furthermore, running:
}   which '(anon)'
} shows that I also now have a named function named (anon).

When the -X option is passed, autoload first creates the placeholder
function definition [as if "autoload $0"] and then calls the function
[eval $0 "$@"] to trigger the actual autoload.  So the error really
is that $0 expands to "(anon)" in that context.

It's important to note that although the placeholder function appears
in "functions" output to have a body consisting of "autoload -X", that
is a convenient fiction -- functions marked for autoloading jump right
to loadautofn() without executing their body.  (The eval trick would
be an infinite loop if this were not the case.)

} The reason for the (eval) error message is that bin_eval is called to
} run the function. This looks a bit of a hack with "$@" being passed as
} an argument but also has other effects; most notable is another round
} of alias expansion but you also get '(eval)' in $funcstack.

This is a case of the implementation of autoload -X falling behind as
other changes occurred around it, though I think the only way to set
this off would be to run it from an anoynmous function as you did.
If scriptname had remained empty in anonymous functions instead of
being forced to '(anon)' for debugging/error message purposes, the
call to autoload -X would have failed with "invalid option(s)" before
reaching eval_autoload().

Aside mostly to PWS:  Is there any way to detect that you are in the
anonymous function?  (!scriptname) means you aren't in any function at
all, which is what bin_functions() is testing for.  Using strcmp() is
not ideal, since one actully is permitted to create a function named
'(anon)' [though it would be ugly/confusing to call it].

IIRC the extra pass of alias expansion was discounted because by the
time you invoke "autoload -X" you presumably have alreay reached the
function via a name that isn't an alias.

OTOH this allows for some games to be played:

--- 8< --- Put this in "autoload-from" in your normal FPATH
{
  local fp=$1 fn=$2
  shift 2
  builtin alias $0=$fn
  FPATH=$fp\:$FPATH builtin autoload -X
} always {
  builtin unalias $0
}
--- 8< ---

Now you can say stuff like

    autoload-from ~/zsh/other my_func some arguments

Of course this is just longhand for

   FPATH=~/zsh/other:$FPATH my_func some arguments

and whether it's a good idea to allow such games is entirely another
matter.

} While looking at that relevant bits of code, I also wonder whether
} the second call to eval_autoload is reachable code: no builtin using
} bin_functions allows both the -m and -X options.

It definitely is not reachable because of the test at about line 2686 in
builtin.c -- the second eval_autoload likely is there for completeness
(in case somebody later adds a builtin that allows a mass autoload).
I've on sometimes wished that "autoload -X something" would immediately
load the body of the function from the file but NOT execute it, which
would translate directly into "autoload -m -X \*" causing all the
functions that are marked for autoloading to populate themselves.

(In fact I think OPT_MINUS(ops,'X') && OPT_ISSET(ops,'m') is impossible
at line 2686 too, but redundant error-checking almost never hurt anyone.)
 
} Trying to think of uses for an explicitly defined call to autoload -X,
} it seems a pity you can't make it autoload a function from a differently
} named file, either by first assigning to ARGV0 or passing a parameter
} to autoload -X.

Per my remark above, I'd rather that passing arguments to -X had a bit
of a different interpretation if it has any at all, and ARGV0 needs to
retain its connection to the name of the shell itself.  However, when
the function_argzero option is set, I don't see any reason why assigning
to $0 could not change the scriptname, which would then propagate to
autoload -X.  But you want to associate a function foo with a file whose
basename is bar, whereas simply changing scriptname would actually load
bar into a new function named bar ... so we'd need to differentiate the
scriptname and the name used by loadautofn().  Hmm.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: autoload -X inside an anonymous function
  2012-09-18 16:58 ` Bart Schaefer
@ 2012-09-19  0:35   ` Bart Schaefer
  2012-09-19  2:28   ` Oliver Kiddle
  1 sibling, 0 replies; 12+ messages in thread
From: Bart Schaefer @ 2012-09-19  0:35 UTC (permalink / raw)
  To: Zsh workers

On Sep 18,  9:58am, Bart Schaefer wrote:
}
} I've on sometimes wished that "autoload -X something" would immediately
} load the body of the function from the file but NOT execute it

Which, duh, is exactly what "autoload +X" does.  How did I forget that?


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: autoload -X inside an anonymous function
  2012-09-18 16:58 ` Bart Schaefer
  2012-09-19  0:35   ` Bart Schaefer
@ 2012-09-19  2:28   ` Oliver Kiddle
  2012-09-19 14:58     ` Bart Schaefer
  1 sibling, 1 reply; 12+ messages in thread
From: Oliver Kiddle @ 2012-09-19  2:28 UTC (permalink / raw)
  To: Zsh workers

Bart wrote:

> Aside mostly to PWS:  Is there any way to detect that you are in the
> anonymous function?  (!scriptname) means you aren't in any function at
> all, which is what bin_functions() is testing for.  Using strcmp() is
> not ideal, since one actully is permitted to create a function named
> '(anon)' [though it would be ugly/confusing to call it].

It might be better to use a named constant for the string "(anon)" so
that a pointer comparison can be used instead of strcmp(). Either that
or add space for flags in the shfunc structure.

> IIRC the extra pass of alias expansion was discounted because by the
> time you invoke "autoload -X" you presumably have alreay reached the
> function via a name that isn't an alias.

It is a bit of a hack, though. I couldn't see an alternative without
making functions in exec.c non-static.

> } While looking at that relevant bits of code, I also wonder whether
> } the second call to eval_autoload is reachable code: no builtin using
> } bin_functions allows both the -m and -X options.
> 
> It definitely is not reachable because of the test at about line 2686 in
> builtin.c -- the second eval_autoload likely is there for completeness
> (in case somebody later adds a builtin that allows a mass autoload).

I would have assumed it was a cut and paste remnant from when -m was
implemented. I can't see any reason why it wouldn't work if you simply
added -m to the list of options accepted by autoload (or -X to
functions). Not that it'd be especially useful; even your "autoload -m
+X \*" example is perhaps only useful for checking there's no parse
errors in any functions.

Oliver



^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: autoload -X inside an anonymous function
  2012-09-19  2:28   ` Oliver Kiddle
@ 2012-09-19 14:58     ` Bart Schaefer
  2012-09-20 19:35       ` Peter Stephenson
  0 siblings, 1 reply; 12+ messages in thread
From: Bart Schaefer @ 2012-09-19 14:58 UTC (permalink / raw)
  To: Zsh workers

On Sep 19,  3:28am, Oliver Kiddle wrote:
} Subject: Re: autoload -X inside an anonymous function
}
} Bart wrote:
} 
} > Aside mostly to PWS:  Is there any way to detect that you are in the
} > anonymous function?  (!scriptname) means you aren't in any function at
} > all, which is what bin_functions() is testing for.
} 
} It might be better to use a named constant for the string "(anon)" so
} that a pointer comparison can be used instead of strcmp().

That would work.  I was hoping there was already something else in the
global state, but it appears that only execfuncdef() knows for sure.

} > } While looking at that relevant bits of code, I also wonder whether
} > } the second call to eval_autoload is reachable code: no builtin using
} > } bin_functions allows both the -m and -X options.
} > 
} > It definitely is not reachable because of the test at about line 2686 in
} > builtin.c -- the second eval_autoload likely is there for completeness
} > (in case somebody later adds a builtin that allows a mass autoload).
} 
} I would have assumed it was a cut and paste remnant from when -m was
} implemented.

Can't be, -m was implemented years before -X was.

} I can't see any reason why it wouldn't work if you simply
} added -m to the list of options accepted by autoload (or -X to
} functions).

I misread the test at 2686 -- that one is using OPT_MINUS(), whereas
the one at 2876 is OPT_ISSET().  So this is there specifically *to*
implement "autoload -m +X", even though autoload doesn't currently
allow -m in its args list.

} Not that it'd be especially useful; even your "autoload -m +X \*"
} example is perhaps only useful for checking there's no parse
} errors in any functions.

The real usage would be to temporarily change FPATH, load all the
functions defined in that alternate path, and then restore the old
FPATH.  This might be to resolve search order dependency issues.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: autoload -X inside an anonymous function
  2012-09-19 14:58     ` Bart Schaefer
@ 2012-09-20 19:35       ` Peter Stephenson
  2012-09-24 18:50         ` Bart Schaefer
  0 siblings, 1 reply; 12+ messages in thread
From: Peter Stephenson @ 2012-09-20 19:35 UTC (permalink / raw)
  To: Zsh workers

On Wed, 19 Sep 2012 07:58:11 -0700
Bart Schaefer <schaefer@brasslantern.com> wrote:
> } I can't see any reason why it wouldn't work if you simply
> } added -m to the list of options accepted by autoload (or -X to
> } functions).
> 
> I misread the test at 2686 -- that one is using OPT_MINUS(), whereas
> the one at 2876 is OPT_ISSET().  So this is there specifically *to*
> implement "autoload -m +X", even though autoload doesn't currently
> allow -m in its args list.

Seems straightforward with an extra test.

I discovered while doing this that "autoload +X _path_files" didn't
work, it doesn't like the absence of the semicolon in the braces.  If
anyone wants to work out why, be me guest.

Index: Completion/Unix/Type/_path_files
===================================================================
RCS file: /cvsroot/zsh/zsh/Completion/Unix/Type/_path_files,v
retrieving revision 1.58
diff -p -u -r1.58 _path_files
--- Completion/Unix/Type/_path_files	5 Sep 2011 22:01:12 -0000	1.58
+++ Completion/Unix/Type/_path_files	20 Sep 2012 19:33:31 -0000
@@ -198,7 +198,7 @@ zstyle -T ":completion:${curcontext}:pat
   path_completion=1
 
 if [[ -n "$compstate[pattern_match]" ]]; then
-  if { [[ -z "$SUFFIX" ]] && _have_glob_qual "$PREFIX" complete } ||
+  if { [[ -z "$SUFFIX" ]] && _have_glob_qual "$PREFIX" complete; } ||
     _have_glob_qual "$SUFFIX" complete; then
     # Copy all glob qualifiers from the line to
     # the patterns used when generating matches
Index: Doc/Zsh/builtins.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/builtins.yo,v
retrieving revision 1.142
diff -p -u -r1.142 builtins.yo
--- Doc/Zsh/builtins.yo	21 Aug 2012 18:03:03 -0000	1.142
+++ Doc/Zsh/builtins.yo	20 Sep 2012 19:33:31 -0000
@@ -108,7 +108,7 @@ ifnzman(noderef(Aliasing)).
 findex(autoload)
 cindex(functions, autoloading)
 cindex(autoloading functions)
-item(tt(autoload) [ {tt(PLUS())|tt(-)}tt(UXktz) ] [ tt(-w) ] [ var(name) ... ])(
+item(tt(autoload) [ {tt(PLUS())|tt(-)}tt(UXkmtz) ] [ tt(-w) ] [ var(name) ... ])(
 Equivalent to tt(functions -u), with the exception of tt(-X)/tt(+X) and
 tt(-w).
 
@@ -129,6 +129,9 @@ undefined and marked for autoloading.  I
 enabled, the function created will contain the contents of the file
 plus a call to the function itself appended to it, thus giving normal
 ksh autoloading behaviour on the first call to the function.
+If the tt(-m) flag is also given each var(name) is treated as a
+pattern and all functions already marked for autoload that match the
+pattern are loaded.
 
 With the tt(-w) flag, the var(name)s are taken as names of files compiled
 with the tt(zcompile) builtin, and all functions defined in them are
Index: Src/builtin.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/builtin.c,v
retrieving revision 1.262
diff -p -u -r1.262 builtin.c
--- Src/builtin.c	8 Sep 2012 19:19:07 -0000	1.262
+++ Src/builtin.c	20 Sep 2012 19:33:31 -0000
@@ -46,7 +46,7 @@ static struct builtin builtins[] =
     BUILTIN(".", BINF_PSPECIAL, bin_dot, 1, -1, 0, NULL, NULL),
     BUILTIN(":", BINF_PSPECIAL, bin_true, 0, -1, 0, NULL, NULL),
     BUILTIN("alias", BINF_MAGICEQUALS | BINF_PLUSOPTS, bin_alias, 0, -1, 0, "Lgmrs", NULL),
-    BUILTIN("autoload", BINF_PLUSOPTS, bin_functions, 0, -1, 0, "ktTUwXz", "u"),
+    BUILTIN("autoload", BINF_PLUSOPTS, bin_functions, 0, -1, 0, "mktTUwXz", "u"),
     BUILTIN("bg", 0, bin_fg, 0, -1, BIN_BG, NULL, NULL),
     BUILTIN("break", BINF_PSPECIAL, bin_break, 0, 1, BIN_BREAK, NULL, NULL),
     BUILTIN("bye", 0, bin_break, 0, 1, BIN_EXIT, NULL, NULL),
@@ -2882,7 +2882,7 @@ bin_functions(char *name, char **argv, O
 	    if ((pprog = patcompile(*argv, PAT_STATIC, 0))) {
 		/* with no options, just print all functions matching the glob pattern */
 		queue_signals();
-		if (!(on|off)) {
+		if (!(on|off) && !OPT_ISSET(ops,'X')) {
 		    scanmatchtable(shfunctab, pprog, 1, 0, DISABLED,
 				   shfunctab->printnode, pflags);
 		} else {

-- 
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: autoload -X inside an anonymous function
  2012-09-20 19:35       ` Peter Stephenson
@ 2012-09-24 18:50         ` Bart Schaefer
  2012-10-05 21:32           ` Peter Stephenson
  0 siblings, 1 reply; 12+ messages in thread
From: Bart Schaefer @ 2012-09-24 18:50 UTC (permalink / raw)
  To: Zsh workers

On Sep 20,  8:35pm, Peter Stephenson wrote:
}
} I discovered while doing this that "autoload +X _path_files" didn't
} work, it doesn't like the absence of the semicolon in the braces.  If
} anyone wants to work out why, be me guest.

Works for me with 4.3.17-test-2 ... and also with 5.0.0-dev-0 just now
compiled from CVS (edited _path_files to remove your semicolon again).

Did you try autoload -z +X ?


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: autoload -X inside an anonymous function
  2012-09-24 18:50         ` Bart Schaefer
@ 2012-10-05 21:32           ` Peter Stephenson
  2012-10-05 21:54             ` Christian Neukirchen
                               ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Peter Stephenson @ 2012-10-05 21:32 UTC (permalink / raw)
  To: Zsh workers

On Mon, 24 Sep 2012 11:50:23 -0700
Bart Schaefer <schaefer@brasslantern.com> wrote:
> On Sep 20,  8:35pm, Peter Stephenson wrote:
> }
> } I discovered while doing this that "autoload +X _path_files" didn't
> } work, it doesn't like the absence of the semicolon in the braces.  If
> } anyone wants to work out why, be me guest.
> 
> Works for me with 4.3.17-test-2 ... and also with 5.0.0-dev-0 just now
> compiled from CVS (edited _path_files to remove your semicolon again).
> 
> Did you try autoload -z +X ?

I've tracked this mystery down... I had "ignoreclosebraces" set because
I had been trying it out from when the option was added.  This is
correctly turned off by the completion code, but it caused loading of
_path_files outside the completion code to fail.

However, this opens a can of worms, or reveals an open can of worms, or
at least perturbs the wave function of the universe sufficiently that
measurement reveals the can of worms to be in the opened state.  (I can,
however, understand that Schroedinger's Cat is likely to remain more
popular than Stephenson's Wormcan.)  Sorry, it's Friday evening.

Naively, you might have thought that simply making ignoreclosebraces an
emulation setting (which might be the right thing to do anyway, as
below) would fix this, but actually we seem to be missing a trick: the
-z flag *doesn't* put the shell into zsh emulation during the load,
although the manual does confusingly use the word "emulation" to
describe its effect.  Furthermore,

  emulate zsh -c 'autoload -z stuff'

(where stuff is a function relying on being able to omit the semicolon
before a closing brace) doesn't work, although

  emulate zsh -c 'autoload +X -z stuff'

does work, because the function is loaded while the emulation is still
in effect.  More explicitly, the emulate in this case is only "sticky"
for functions declared in it, not for functions marked for autoload in
it.  Maybe this needs to change?  I explicitly did it this way:

	    /* No sticky emulation for autoloaded functions */
	    shf->emulation = 0;

and I wrote in the accompanying message (zsh-workers/26546):

  Note that sticky emulation is not propagated to autoloaded functions,
  neither when the autoload is set up nor when they are loaded, nor does
  autoloading a function provide the same sort of firewall as sticky
  emulation.  Defining a function with the special "functions" parameter
  is treated the same as defining a function inline in the normal way.

but I'm not sure I thought this through properly.  If I got it wrong,
the fix for the case here is trivial (and I've verified it works).
The more I think about it, the less I can think of a good reason for
having an autoload declared within a sticky emulation lose the
stickiness.

Beyond that, I'm not sure what the answer is; is making -z force zsh
emulation reasonable?  I don't necessarily think making -k force ksh
emulation is reasonable, the function might be a zsh function that just
happens to be written using the ksh format for autoloads.

I may simply be expecting too much, though it would certainly be good to
be able to ensure a function can be loaded irrespective of the options
currently in effect.

On the whole I'd be inclined to reverse my decision not to propagate
stickiness to autoloads, and to document that -z only affects the
autoload style and that

  emulate zsh -c 'autoload -Uz ...'

is the way to ensure functions are loaded with appropriate options.
This generalises in a natural way to other emulations in a way
overloading the -z flag doesn't.

Index: Src/options.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/options.c,v
retrieving revision 1.62
diff -p -u -r1.62 options.c
--- Src/options.c	21 Aug 2012 18:03:03 -0000	1.62
+++ Src/options.c	5 Oct 2012 21:02:18 -0000
@@ -160,7 +160,7 @@ static struct optname optns[] = {
 {{NULL, "histverify",	      0},			 HISTVERIFY},
 {{NULL, "hup",		      OPT_EMULATE|OPT_ZSH},	 HUP},
 {{NULL, "ignorebraces",	      OPT_EMULATE|OPT_SH},	 IGNOREBRACES},
-{{NULL, "ignoreclosebraces",  0},			 IGNORECLOSEBRACES},
+{{NULL, "ignoreclosebraces",  OPT_EMULATE},		 IGNORECLOSEBRACES},
 {{NULL, "ignoreeof",	      0},			 IGNOREEOF},
 {{NULL, "incappendhistory",   0},			 INCAPPENDHISTORY},
 {{NULL, "interactive",	      OPT_SPECIAL},		 INTERACTIVE},

-- 
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: autoload -X inside an anonymous function
  2012-10-05 21:32           ` Peter Stephenson
@ 2012-10-05 21:54             ` Christian Neukirchen
  2012-10-07 17:51               ` Peter Stephenson
  2012-10-05 22:24             ` Peter Stephenson
  2012-10-06  7:56             ` Bart Schaefer
  2 siblings, 1 reply; 12+ messages in thread
From: Christian Neukirchen @ 2012-10-05 21:54 UTC (permalink / raw)
  To: zsh-workers

Peter Stephenson <p.w.stephenson@ntlworld.com> writes:

> I've tracked this mystery down... I had "ignoreclosebraces" set because
> I had been trying it out from when the option was added.

I still feel bad for proposing this option.  It made nothing but trouble.

Sorry,
-- 
Christian Neukirchen  <chneukirchen@gmail.com>  http://chneukirchen.org


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: autoload -X inside an anonymous function
  2012-10-05 21:32           ` Peter Stephenson
  2012-10-05 21:54             ` Christian Neukirchen
@ 2012-10-05 22:24             ` Peter Stephenson
  2012-10-06  7:56             ` Bart Schaefer
  2 siblings, 0 replies; 12+ messages in thread
From: Peter Stephenson @ 2012-10-05 22:24 UTC (permalink / raw)
  To: Zsh workers

On Fri, 5 Oct 2012 22:32:28 +0100
Peter Stephenson <p.w.stephenson@ntlworld.com> wrote:
> On the whole I'd be inclined to reverse my decision not to propagate
> stickiness to autoloads, and to document that -z only affects the
> autoload style and that
> 
>   emulate zsh -c 'autoload -Uz ...'
> 
> is the way to ensure functions are loaded with appropriate options.

This would be the corresponding patch, but I'll wait for reaction.

One slight subtlety is that I only changed the use of sticky emulation
at the point where the function is marked for autoload; this causes the
sticky emulation to be in effect during the autoload itself, and it
remains in effect while the function is being defined so propagates to
the new function definition which retains the same sticky emulation for
execution.  If you don't believe me, believe the test...

Index: README
===================================================================
RCS file: /cvsroot/zsh/zsh/README,v
retrieving revision 1.77
diff -p -u -r1.77 README
--- README	15 Jun 2012 21:23:42 -0000	1.77
+++ README	5 Oct 2012 22:18:58 -0000
@@ -30,8 +30,38 @@ Zsh is a shell with lots of features.  F
 file FEATURES, and for the latest changes see NEWS.  For more
 details, see the documentation.
 
-Possible incompatibilities
----------------------------
+Incompatibilities between 5.0.0 and 5.0.1
+-----------------------------------------
+
+In 5.0.0, the new "sticky" emulation feature was applied to functions
+explicitly declared within an expression following `emulate ... -c', but
+did not apply to functions marked for autoload in that expression.  This
+was not documented and experience suggests it was inconvenient, so in
+5.0.1 autoloads also have the sticky property.
+
+In other words,
+
+  emulate zsh -c 'func() { ... }'
+
+behaves the same way in 5.0.0 and 5.0.1, with the function func always being
+run in native zsh emulation regardless of the current option settings.
+However,
+
+  emulate zsh -c 'autoload -Uz func'
+
+behaves differently: in 5.0.0, func was loaded with the options in
+effect at the point where it was first run, and subsequently run with
+whatever options were in effect at that point; in 5.0.1, func is loaded
+with native zsh emulation options and run with those same options.  This
+is now the recommended way of ensuring a function is loaded and run with
+a consistent set of options.
+
+Note that the `autoload -z' has never affected the options applied when
+the function is loaded or run, only the effect of the KSH_AUTOLOAD
+option at the point the function is loaded.
+
+Possible incompatibilities between 4.2 and 5.0
+----------------------------------------------
 
 Here are some incompatibilities in the shell since the 4.2 series of
 releases.  It is hoped most users will not be adversely affected by these.
Index: Doc/Zsh/builtins.yo
===================================================================
RCS file: /cvsroot/zsh/zsh/Doc/Zsh/builtins.yo,v
retrieving revision 1.143
diff -p -u -r1.143 builtins.yo
--- Doc/Zsh/builtins.yo	21 Sep 2012 19:08:36 -0000	1.143
+++ Doc/Zsh/builtins.yo	5 Oct 2012 22:18:58 -0000
@@ -137,10 +137,19 @@ With the tt(-w) flag, the var(name)s are
 with the tt(zcompile) builtin, and all functions defined in them are
 marked for autoloading.
 
-The flags tt(-z) and tt(-k) mark the function to be autoloaded in
-native or ksh emulation, as if the option tt(KSH_AUTOLOAD) were
-unset or were set, respectively.  The flags override the setting of
-the option at the time the function is loaded.
+The flags tt(-z) and tt(-k) mark the function to be autoloaded using the
+zsh or ksh style, as if the option tt(KSH_AUTOLOAD) were unset or were
+set, respectively.  The flags override the setting of the option at the
+time the function is loaded.
+
+Note that the tt(autoload) command makes no attempt to ensure the
+shell options set during the loading or execution of the file have
+any particular value.  For this, the tt(emulate) command can be used:
+
+example(emulate zsh -c 'autoload -Uz var(func)')
+
+arranges that when var(func) is loaded the shell is in native tt(zsh)
+emulation, and this emulation is also applied when var(func) is run.
 )
 findex(bg)
 cindex(jobs, backgrounding)
@@ -393,6 +402,7 @@ ifnzman(noderef(Invocation))\
 ifzman(the section INVOCATION in zmanref(zsh)),
 except that `tt(-o EMACS)' and `tt(-o VI)' may not be used.  Flags such
 as `tt(+r)'/`tt(+o RESTRICTED)' may be prohibited in some circumstances.
+
 If tt(-c) var(arg) appears in var(flags), var(arg) is evaluated while the
 requested emulation is temporarily in effect.  In this case the emulation
 mode and all options are restored to their previous values before
@@ -409,7 +419,10 @@ If the function is called when the stick
 effect, either within an `tt(emulate) var(shell) tt(-c)' expression or
 within another function with the same sticky emulation, entry and exit
 from the function do not cause options to be altered (except due to
-standard processing such as the tt(LOCAL_OPTIONS) option).
+standard processing such as the tt(LOCAL_OPTIONS) option).  This also
+applies to functions marked for autoload within the sticky emulation;
+the appropriate set of options will be applied at the point the
+function is loaded as well as when it is run.
 
 For example:
 
Index: Src/builtin.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/builtin.c,v
retrieving revision 1.263
diff -p -u -r1.263 builtin.c
--- Src/builtin.c	21 Sep 2012 19:08:36 -0000	1.263
+++ Src/builtin.c	5 Oct 2012 22:18:58 -0000
@@ -2944,8 +2944,7 @@ bin_functions(char *name, char **argv, O
 	    shf = (Shfunc) zshcalloc(sizeof *shf);
 	    shf->node.flags = on;
 	    shf->funcdef = mkautofn(shf);
-	    /* No sticky emulation for autoloaded functions */
-	    shf->emulation = 0;
+	    shf->emulation = sticky_emulation;
 	    shfunctab->addnode(shfunctab, ztrdup(*argv), shf);
 
 	    if (signum != -1) {
Index: Test/C04funcdef.ztst
===================================================================
RCS file: /cvsroot/zsh/zsh/Test/C04funcdef.ztst,v
retrieving revision 1.10
diff -p -u -r1.10 C04funcdef.ztst
--- Test/C04funcdef.ztst	3 Aug 2011 18:45:19 -0000	1.10
+++ Test/C04funcdef.ztst	5 Oct 2012 22:18:58 -0000
@@ -251,6 +251,23 @@
 >foo1
 >bar2
 
+  (
+  setopt ignorebraces
+  fpath=(.)
+  print "{ echo OK }\n[[ -o ignorebraces ]] || print 'ignorebraces is off'" \
+      >emufunctest
+  (autoload -z emufunctest; emufunctest) 2>&1
+  emulate zsh -c 'autoload -Uz emufunctest'
+  emufunctest
+  [[ -o ignorebraces ]] && print 'ignorebraces is still on here'
+  )
+0:sticky emulation applies to autoloads and autoloaded function execution
+>emufunctest:3: parse error near `\n'
+>OK
+>ignorebraces is off
+>ignorebraces is still on here
+
+
 %clean
 
  rm -f file.in file.out

-- 
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: autoload -X inside an anonymous function
  2012-10-05 21:32           ` Peter Stephenson
  2012-10-05 21:54             ` Christian Neukirchen
  2012-10-05 22:24             ` Peter Stephenson
@ 2012-10-06  7:56             ` Bart Schaefer
  2 siblings, 0 replies; 12+ messages in thread
From: Bart Schaefer @ 2012-10-06  7:56 UTC (permalink / raw)
  To: Zsh workers

On Oct 5, 10:32pm, Peter Stephenson wrote:
}
} However, this opens a can of worms, or reveals an open can of worms, or
} at least perturbs the wave function of the universe sufficiently that
} measurement reveals the can of worms to be in the opened state.  (I can,
} however, understand that Schroedinger's Cat is likely to remain more
} popular than Stephenson's Wormcan.)  Sorry, it's Friday evening.

Apparently it's now possible to determine that there are in fact worms
in the can, even if you haven't opened it, which seems a much better
metaphor for what actually goes on in quantum superposition than does
a zombie cat.  It's evidently also possible for two events to be each
other's causes, which is something the zsh code base seems to be quite
suited to demonstrate.
 
}   emulate zsh -c 'autoload +X -z stuff'
} 
} does work, because the function is loaded while the emulation is still
} in effect.  More explicitly, the emulate in this case is only "sticky"
} for functions declared in it, not for functions marked for autoload in
} it.  Maybe this needs to change?

I hadn't followed before that you had to explicitly make this not be the
case:

} 	    /* No sticky emulation for autoloaded functions */
} 	    shf->emulation = 0;

I'm generally in favor of your patch from 30718.  I'm mildly concerned
about functions that, when executed, define or autoload other functions,
but even if that's a real issue it could be fixed by another emulate -c
scope.
 
} Beyond that, I'm not sure what the answer is; is making -z force zsh
} emulation reasonable?  I don't necessarily think making -k force ksh
} emulation is reasonable, the function might be a zsh function that just
} happens to be written using the ksh format for autoloads.

I think changing the semantics of autoload -z is probably going too far.
A new option to autoload that caused emulation to be in effect would be
OK, but as the effect can already be had with an emulate wrapper, that
might be unnecessary TMTOWTDI.

} This generalises in a natural way to other emulations in a way
} overloading the -z flag doesn't.

Agree.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: autoload -X inside an anonymous function
  2012-10-05 21:54             ` Christian Neukirchen
@ 2012-10-07 17:51               ` Peter Stephenson
  0 siblings, 0 replies; 12+ messages in thread
From: Peter Stephenson @ 2012-10-07 17:51 UTC (permalink / raw)
  To: zsh-workers

On Fri, 05 Oct 2012 23:54:41 +0200
Christian Neukirchen <chneukirchen@gmail.com> wrote:
> > I've tracked this mystery down... I had "ignoreclosebraces" set because
> > I had been trying it out from when the option was added.
> 
> I still feel bad for proposing this option.  It made nothing but trouble.

Heh.  It's not actually the option that's the problem, just one aspect
of it I missed and the fact that it revealed certain other things going
on.

Bart wrote:
> I'm generally in favor of your patch from 30718.  I'm mildly concerned
> about functions that, when executed, define or autoload other functions,
> but even if that's a real issue it could be fixed by another emulate -c
> scope.

At this stage, I'm not even sure what issues it might reveal.  I've
committed the change.

-- 
Peter Stephenson <p.w.stephenson@ntlworld.com>
Web page now at http://homepage.ntlworld.com/p.w.stephenson/


^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2012-10-07 17:52 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-09-18  2:12 autoload -X inside an anonymous function Oliver Kiddle
2012-09-18 16:58 ` Bart Schaefer
2012-09-19  0:35   ` Bart Schaefer
2012-09-19  2:28   ` Oliver Kiddle
2012-09-19 14:58     ` Bart Schaefer
2012-09-20 19:35       ` Peter Stephenson
2012-09-24 18:50         ` Bart Schaefer
2012-10-05 21:32           ` Peter Stephenson
2012-10-05 21:54             ` Christian Neukirchen
2012-10-07 17:51               ` Peter Stephenson
2012-10-05 22:24             ` Peter Stephenson
2012-10-06  7:56             ` Bart Schaefer

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).