zsh-workers
 help / color / mirror / code / Atom feed
* zsh function declaration bug
@ 2019-01-30 17:46 Mitchell Gildenberg
  2019-01-31 13:11 ` dana
  0 siblings, 1 reply; 3+ messages in thread
From: Mitchell Gildenberg @ 2019-01-30 17:46 UTC (permalink / raw)
  To: zsh-workers

[-- Attachment #1: Type: text/plain, Size: 1090 bytes --]

Hello,

I noticed some interesting behavior when declaring zsh functions without
specifying the `function` keyword. When I declare a function that is a
prefix of some other item in my path or another alias, the function that is
a prefix is called instead.  For example:

------------
(macbook) ➜ mgild $ zsh --version
zsh 5.3 (x86_64-apple-darwin17.0)
(macbook) ➜ mgild $ ls
Applications/ Desktop/      Documents/    Downloads/    Library/
Movies/       Music/        Pictures/     Public/
(macbook) ➜ mgild $ l(){echo "hello"}
(macbook) ➜ mgild $ ls
hello
(macbook) ➜ mgild $
-------------- (zsh 5.5 exhibits different behavior)
➜ mgild $ zsh --version
zsh 5.5 (x86_64-debian-linux-gnu)
➜ mgild $ ls
Desktop Documents
➜ mgild $ l(){ echo "hello"}
zsh: defining function based on alias `ls'
zsh: parse error near `()'
--------------
zsh 5.5 seems to exhibit different behavior, but it is still unexpectedly
failing to create the function.

Let me know if any more information is required.

Thank you.

Mitchell Gildenberg
mgild@google.com

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

* Re: zsh function declaration bug
  2019-01-30 17:46 zsh function declaration bug Mitchell Gildenberg
@ 2019-01-31 13:11 ` dana
  2019-01-31 14:00   ` Peter Stephenson
  0 siblings, 1 reply; 3+ messages in thread
From: dana @ 2019-01-31 13:11 UTC (permalink / raw)
  To: Mitchell Gildenberg; +Cc: zsh-workers

On 30 Jan 2019, at 11:46, Mitchell Gildenberg <mgild@google.com> wrote:
>➜ mgild $ l(){ echo "hello"}
>zsh: defining function based on alias `ls'
>zsh: parse error near `()'

Presumably you have an alias l=ls, which is being expanded because the l in
l() { ... } is considered to be in command position. workers/40300 made this
an error by default, since the expansion behaviour is generally unexpected

If you don't need the l alias, you can just unalias it. Otherwise it will
work with the function key word like you said, or if you put the definition in
a file rather than entering it at the command line. But i'm guessing you don't
actually want an alias and a function with the same name anyway

dana


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

* Re: zsh function declaration bug
  2019-01-31 13:11 ` dana
@ 2019-01-31 14:00   ` Peter Stephenson
  0 siblings, 0 replies; 3+ messages in thread
From: Peter Stephenson @ 2019-01-31 14:00 UTC (permalink / raw)
  To: zsh-workers

On Thu, 2019-01-31 at 07:11 -0600, dana wrote:
> On 30 Jan 2019, at 11:46, Mitchell Gildenberg <mgild@google.com> wrote:
> >
> > ➜ mgild $ l(){ echo "hello"}
> > zsh: defining function based on alias `ls'
> > zsh: parse error near `()'
> Presumably you have an alias l=ls, which is being expanded because the l in
> l() { ... } is considered to be in command position. workers/40300 made this
> an error by default, since the expansion behaviour is generally unexpected
>
> If you don't need the l alias, you can just unalias it. Otherwise it will
> work with the function key word like you said, or if you put the definition in
> a file rather than entering it at the command line. But i'm guessing you don't
> actually want an alias and a function with the same name anyway

Yes, this is described in the FAQ, quoted at the bottom (it lives in the
source distribution in the Etc directory, or at
http://zsh.sourceforge.net/FAQ/).  This was written before you got the
error message when this happened.

The new error is basically there to tell you "you don't want to do
this".  The old behaviour --- silently defining functions based on
aliases --- was almost never what you wanted.

pws


There is one other serious problem with aliases: consider

    alias l='/bin/ls -F'
    l() { /bin/ls -la "$@" | more }

  `l' in the function definition is in command position and is expanded
  as an alias, defining `/bin/ls' and `-F' as functions which call
  `/bin/ls', which gets a bit recursive.  This can be avoided if you use
  `function' to define a function, which doesn't expand aliases.  It is
  possible to argue for extra warnings somewhere in this mess.

One workaround for this is to use the "function" keyword instead:

    alias l='/bin/ls -F'
    function l { /bin/ls -la "$@" | more }

  The `l' after `function' is not expanded.  Note you don't need
  the `()' in this case, although it's harmless.

You need to be careful if you are defining a function with multiple
  names; most people don't need to do this, so it's an unusual problem,
  but in case you do you should be aware that in versions of the shell
  before 5.1 names after the first were expanded:

    function a b c { ... }

  Here, `b' and `c', but not `a', have aliases expanded.
  This oddity was fixed in version 5.1.

The rest of this item assumes you use the (more common,
  but equivalent) `()' definitions.

Bart Schaefer's rule is:  Define first those aliases you expect to
  use in the body of a function, but define the function first if the
  alias has the same name as the function.

If you aware of the problem, you can always escape part or all of the
  name of the function:

     'l'() { /bin/ls -la "$@" | more }

  Adding the quotes has no effect on the function definition, but
  suppresses alias expansion for the function name.  Hence this is
  guaranteed to be safe---unless you are in the habit of defining
  aliases for expressions such as 'l', which is valid, but probably
  confusing.



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

end of thread, other threads:[~2019-01-31 14:10 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-01-30 17:46 zsh function declaration bug Mitchell Gildenberg
2019-01-31 13:11 ` dana
2019-01-31 14:00   ` Peter Stephenson

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