-
Notifications
You must be signed in to change notification settings - Fork 27
Description
What is the output of the following code?
(Hint: it's not the shell invocation or the name of the script as one might expect.)
`{echo echo $0}
This behavior is documented in the man page:
If, as the most common case, a function variable is bound to a lambda, when the function is invoked, the variable
$0is bound (dynamically, see below) to the name of the function.
It sounds reasonably intuitive, but it's awful in practice, and i'm not the first to be confused by it:
I tried to get the name a script was called by hence I did:
NAME=`{basename $0}giving me a value of '%backquote' for '$NAME'.
Similarly, the following excerpt from examples/esrc.haahr once worked because fn-%backquote = $&backquote was used, meaning $0 was not set, but %backquote became a normal lambda, leading to the same trouble:
fn -- {
eval `` '' { $0^p $* }
#want: `` '' { --p $* }
#have: `` '' { %backquotep $* }
}
If one defines fn-if = @ { $&if $* }, then many other examples are broken as well:
# examples/number.es
if { ~ $* *[~0-9,.]* } \
{ throw error $0 $0: invalid character in argument. }
#want: throw error number number: invalid character in argument.
#have: throw error if if: invalid character in argument. }
# examples/friedman/lib/subr.es
if { ~ $* () '' } \
{ * = `{ local (fn-$0 =) $0 } }
#want: * = `{ local (fn-whoami =) whoami }
# undefine fn-whoami, so whoami(1) is invoked
#have: * = `{ local (fn-%backquote =) whoami }
# invokes fn-whoami repeatedly, not whoami(1)
The general expectation appears to be that $0 is not dynamically scoped.
Can anybody think of a good reason to retain this confusing behavior?