Почему имена числовых функций не разрешены?

Рассмотрим следующее:

$ ksh -c '1(){ echo hi;};1' ksh: 1: invalid function name $ dash -c '1(){ echo hi;};1' dash: 1: Syntax error: Bad function name $ bash -c '1(){ echo hi;};1' bash: `1': not a valid identifier bash: 1: command not found $ mksh -c '1(){ echo hi;};1' hi

В основном, я пытался объявить функции 1 и 0, которые были бы сокращенными для true и false, но, как вы можете видеть Я столкнулся с проблемой использования числовых имен в функциях. Такое же поведение происходит с псевдонимами и двузначными именами.

Вопрос «почему»? Предусмотрено ли это POSIX? или просто причуда борнеподобных оболочек?

См. также связанный с этим вопрос.

10
задан 17 December 2017 в 09:14

9 ответов

POSIX говорит:

2.9.5 Функция Определение команды Функция - это определяемое пользователем имя, которое используется как простая команда для вызова составной команды с новыми позиционными параметрами. Функция определяется с помощью команды определения функции. Формат команды определения функции выглядит следующим образом:
 fname ( ) compound-command [io-redirect ...]
Функция называется fname; приложение должно гарантировать, что это имя (см. XBD Name) и что это не имя специальной встроенной утилиты. Реализация может допускать использование других символов в имени функции в качестве расширения. Реализация должна поддерживать отдельные пространства имен для функций и переменных.

И:

2.9.5 Определение функции Команда

Функция - это определяемое пользователем имя, которое используется как простая команда для вызова составная команда с новыми позиционными параметрами. Функция определена с помощью команды определения функции.

Примечание. Набор переносных символов подробно описан в переносном наборе символов.

В командном языке оболочки слово, состоящее исключительно из символов подчеркивания, цифр и алфавитов из переносного набора символов. Первый символ имени не является цифрой.

14
ответ дан 22 May 2018 в 16:06
  • 1
    Тем не менее POSIX не совсем скажет, почему, но я возьму его как «Потому что стандарты " ответ. благодаря – Sergiy Kolodyazhnyy 19 November 2017 в 07:06
  • 2
    @ СергейГолодяжный, я бы сказал, что это унаследованная вещь. Этот стандарт для имен довольно распространен и в других вещах (имена IIRC C также соответствуют одному и тому же стандарту), поэтому, вероятно, это Unix. Кроме того, в C это упрощает анализ – muru 19 November 2017 в 07:08
  • 3
    @muru в C это принесло бы некоторую двусмысленность, если бы это было разрешено. Например. что означало бы 1L? Имя функции? Или буква long int? – Ruslan 19 November 2017 в 12:46
  • 4
    Добавляя выше, стоит отметить, что в C имя полезной функции может действовать как указатель на эту функцию. Это позволяет передавать функции как параметры функции, хранить ссылки на них в переменных и т. Д. Часто используется для обратных вызовов. Это в отличие от имени функции, за которой следует (), возможно, с аргументами внутри, что означает вызов соответствующей функции (и принимает значение, возвращаемое вызываемой функцией). Поэтому, если у вас есть функция int f() { return 42; } в C, f действительна в контексте указателя, а f() действительна в контексте, отличном от указателя, целого. – Michael Kjörling 19 November 2017 в 23:27

POSIX говорит:

2.9.5 Функция Определение команды Функция - это определяемое пользователем имя, которое используется как простая команда для вызова составной команды с новыми позиционными параметрами. Функция определяется с помощью команды определения функции. Формат команды определения функции выглядит следующим образом: fname ( ) compound-command [io-redirect ...] Функция называется fname; приложение должно гарантировать, что это имя (см. XBD Name) и что это не имя специальной встроенной утилиты. Реализация может допускать использование других символов в имени функции в качестве расширения. Реализация должна поддерживать отдельные пространства имен для функций и переменных.

И:

2.9.5 Определение функции Команда

Функция - это определяемое пользователем имя, которое используется как простая команда для вызова составная команда с новыми позиционными параметрами. Функция определена с помощью команды определения функции.

Примечание. Набор переносных символов подробно описан в переносном наборе символов.

В командном языке оболочки слово, состоящее исключительно из символов подчеркивания, цифр и алфавитов из переносного набора символов. Первый символ имени не является цифрой.

14
ответ дан 18 July 2018 в 03:02

POSIX говорит:

2.9.5 Функция Определение команды Функция - это определяемое пользователем имя, которое используется как простая команда для вызова составной команды с новыми позиционными параметрами. Функция определяется с помощью команды определения функции. Формат команды определения функции выглядит следующим образом: fname ( ) compound-command [io-redirect ...] Функция называется fname; приложение должно гарантировать, что это имя (см. XBD Name) и что это не имя специальной встроенной утилиты. Реализация может допускать использование других символов в имени функции в качестве расширения. Реализация должна поддерживать отдельные пространства имен для функций и переменных.

И:

2.9.5 Определение функции Команда

Функция - это определяемое пользователем имя, которое используется как простая команда для вызова составная команда с новыми позиционными параметрами. Функция определена с помощью команды определения функции.

Примечание. Набор переносных символов подробно описан в переносном наборе символов.

В командном языке оболочки слово, состоящее исключительно из символов подчеркивания, цифр и алфавитов из переносного набора символов. Первый символ имени не является цифрой.

14
ответ дан 24 July 2018 в 17:43

Это стандарт на многих языках, чтобы предотвратить путаницу между математическими операциями и переменными или функциями или методами.

Рассмотрим:

var 1 = 100

print 1*10 //should return 10 but would instead return 1000

var x = 5
x += 1
print x //returns 105, not 6    

def 100(num)
  return num * 1000
end

var y = 10 + 100(10)
print y // returns 100010 instead of 1010

Как вы можете видеть, если числа были разрешены как имена переменных или функций, выполнение математики позже в программе может стать очень запутанным, и вам придется придумайте креативные обходные пути, если вам нужно на самом деле сделать математику с этими номерами позже. Это также может привести к неожиданным результатам на некоторых языках. Представьте, что вы увеличиваете число для цикла, но одна из цифр уже является переменной, равной строке. Это немедленно вызовет ошибку. Если вы не являетесь оригинальным автором кода, эта ошибка может занять довольно много времени.

Вкратце, поэтому большинство языков не позволяют использовать число в качестве имени переменная или функция или метод или т. д.

13
ответ дан 22 May 2018 в 16:06
  • 1
    Я собирался комментировать " но переменные в оболочке должны быть добавлены с $ для расширения " но опять же, если оболочка вдохновлена ​​другими языками, это нормально, я думаю, плюс в арифметическом расширении (( переменным не требуется иметь ведущие $. Хорошо, я понимаю, что – Sergiy Kolodyazhnyy 19 November 2017 в 08:22
  • 2
    Да, это соглашение, потому что оно создаст неожиданные результаты почти на каждом языке, но даже в ситуации, когда это сработает, это может сделать код очень сложным для понимания для тех, кому придется работать над вашим кодом после вас. – Josh 19 November 2017 в 08:27
  • 3
    @SergiyKolodyazhnyy арифметическое расширение позволяет ссылаться на имена переменных без $, так что есть. Но это, вероятно, является второстепенным по сравнению с другой причиной «просто следуя общей конвенции». – hobbs 19 November 2017 в 11:03
  • 4
    @hobbs yep, абсолютно согласен с этим – Sergiy Kolodyazhnyy 19 November 2017 в 11:06
  • 5
    Это "большинство языков" объяснение мало смысла для снарядов. У всех оболочек в стиле Бурна есть параметры, имена которых выглядят как числовые литералы или операторы: 0 для имени оболочки или скрипта, 1, 2, ..., для позиционных параметров, [ f4] для них, - для разрешенных опций, ? для последнего статуса выхода и ! для самого нового асинхронного задания PID. (Таким образом, даже в $(( )) часто требуется $.) Код, показанный здесь, чтобы продемонстрировать предлагаемое обоснование, не является скриптом для любой оболочки в стиле Бурна, поскольку нет возможности продемонстрировать это путь, поскольку он не применяет к ним . – Eliah Kagan 19 November 2017 в 17:57

В C рассмотрим выражение типа:

1000l + 2.0f;

Является ли 1000l переменной или константой? Поскольку имена переменных не могут начинаться с цифры, она должна быть постоянной. Это упрощает и упрощает синтаксический анализ (опечатки вроде 1000k могут быть легко пойманы). Также проще иметь одно правило для имен переменных и функций, поскольку функции также могут рассматриваться как переменные. Теперь, разумеется, парсеры намного сложнее и мощнее, и у нас есть такие вещи, как пользовательские литералы на C ++. Но в те древние времена предыстории, жертвуя немного ненужной гибкостью, вы могли бы значительно сократить время компиляции (или интерпретации) (и люди все еще жалуются на время компиляции C ++).

И вы можете увидеть эффекты влияния C на весь язык оболочки, поэтому неудивительно, что оболочка Bourne (или оболочка C) и, следовательно, POSIX, ограничила класс разрешенных имен такими же, как у C.

10
ответ дан 22 May 2018 в 16:06
  • 1
    Поскольку объяснения go, это правильный. Это not , что те же соображения применимы ко всем языкам или что оболочки в стиле Бурна имеют синтаксис, аналогичный синтаксису C, но что культура, связанная с C, была сильной, и дизайнеры оболочек должны были придумать некоторые гарантируют, какие идентификаторы будут разрешены. Я думаю, что это могло бы использовать примеры «вы можете увидеть эффекты влияния C во всем языке оболочки», поскольку сходства между ними действительно не превосходят перевесы (подумайте, какие числа считаются истинными , например). Тем не менее, этот ответ правильный. – Eliah Kagan 20 November 2017 в 08:46
  • 2
    @ Eliah, возможно, число вещей также является прямым следствием статусов выхода для успеха и неудачи в C, поэтому я склонен думать об успехах и неудачах вместо истинных и ложных при написании тестов на оболочку. Вы правы в том, что много синтаксиса оболочки не похоже на C, но примеры включают скобки, точки с запятой, короткое замыкание && и ||, отсутствие поддержки ASCII nul в строках, – Olorin 20 November 2017 в 09:41

Это стандарт на многих языках, чтобы предотвратить путаницу между математическими операциями и переменными или функциями или методами.

Рассмотрим:

var 1 = 100 print 1*10 //should return 10 but would instead return 1000 var x = 5 x += 1 print x //returns 105, not 6 def 100(num) return num * 1000 end var y = 10 + 100(10) print y // returns 100010 instead of 1010

Как вы можете видеть, если числа были разрешены как имена переменных или функций, выполнение математики позже в программе может стать очень запутанным, и вам придется придумайте креативные обходные пути, если вам нужно на самом деле сделать математику с этими номерами позже. Это также может привести к неожиданным результатам на некоторых языках. Представьте, что вы увеличиваете число для цикла, но одна из цифр уже является переменной, равной строке. Это немедленно вызовет ошибку. Если вы не являетесь оригинальным автором кода, эта ошибка может занять довольно много времени.

Вкратце, поэтому большинство языков не позволяют использовать число в качестве имени переменная или функция или метод или т. д.

13
ответ дан 18 July 2018 в 03:02

В C рассмотрим выражение типа:

1000l + 2.0f;

Является ли 1000l переменной или константой? Поскольку имена переменных не могут начинаться с цифры, она должна быть постоянной. Это упрощает и упрощает синтаксический анализ (опечатки вроде 1000k могут быть легко пойманы). Также проще иметь одно правило для имен переменных и функций, поскольку функции также могут рассматриваться как переменные. Теперь, разумеется, парсеры намного сложнее и мощнее, и у нас есть такие вещи, как пользовательские литералы на C ++. Но в те древние времена предыстории, жертвуя немного ненужной гибкостью, вы могли бы значительно сократить время компиляции (или интерпретации) (и люди все еще жалуются на время компиляции C ++).

И вы можете увидеть эффекты влияния C на весь язык оболочки, поэтому неудивительно, что оболочка Bourne (или оболочка C) и, следовательно, POSIX, ограничила класс разрешенных имен такими же, как у C.

10
ответ дан 18 July 2018 в 03:02

Это стандарт на многих языках, чтобы предотвратить путаницу между математическими операциями и переменными или функциями или методами.

Рассмотрим:

var 1 = 100 print 1*10 //should return 10 but would instead return 1000 var x = 5 x += 1 print x //returns 105, not 6 def 100(num) return num * 1000 end var y = 10 + 100(10) print y // returns 100010 instead of 1010

Как вы можете видеть, если числа были разрешены как имена переменных или функций, выполнение математики позже в программе может стать очень запутанным, и вам придется придумайте креативные обходные пути, если вам нужно на самом деле сделать математику с этими номерами позже. Это также может привести к неожиданным результатам на некоторых языках. Представьте, что вы увеличиваете число для цикла, но одна из цифр уже является переменной, равной строке. Это немедленно вызовет ошибку. Если вы не являетесь оригинальным автором кода, эта ошибка может занять довольно много времени.

Вкратце, поэтому большинство языков не позволяют использовать число в качестве имени переменная или функция или метод или т. д.

13
ответ дан 24 July 2018 в 17:43
  • 1
    Я собирался комментировать & quot; но переменные в оболочке должны быть добавлены с $ для расширения & quot; но опять же, если оболочка вдохновлена ​​другими языками, это нормально, я думаю, плюс в арифметическом расширении (( переменным не требуется иметь ведущие $. Хорошо, я понимаю, что – Sergiy Kolodyazhnyy 19 November 2017 в 08:22
  • 2
    Да, это соглашение, потому что оно создаст неожиданные результаты почти на каждом языке, но даже в ситуации, когда это сработает, это может сделать код очень сложным для понимания для тех, кому придется работать над вашим кодом после вас. – Josh 19 November 2017 в 08:27
  • 3
    @SergiyKolodyazhnyy арифметическое расширение позволяет ссылаться на имена переменных без $, так что есть. Но это, вероятно, является второстепенным по сравнению с другой причиной «просто следуя общей конвенции». – hobbs 19 November 2017 в 11:03
  • 4
    @hobbs yep, абсолютно согласен с этим – Sergiy Kolodyazhnyy 19 November 2017 в 11:06
  • 5
    Это "большинство языков" объяснение мало смысла для снарядов. У всех оболочек в стиле Бурна есть параметры, имена которых выглядят как числовые литералы или операторы: 0 для имени оболочки или скрипта, 1, 2, ..., для позиционных параметров, * для них, - для разрешенных опций, ? для последнего статуса выхода и ! для самого нового асинхронного задания PID. (Таким образом, даже в $(( )) часто требуется $.) Код, показанный здесь, чтобы продемонстрировать предлагаемое обоснование, не является скриптом для любой оболочки в стиле Бурна, поскольку нет возможности продемонстрировать это путь, поскольку он не применяет к ним . – Eliah Kagan 19 November 2017 в 17:57

В C рассмотрим выражение типа:

1000l + 2.0f;

Является ли 1000l переменной или константой? Поскольку имена переменных не могут начинаться с цифры, она должна быть постоянной. Это упрощает и упрощает синтаксический анализ (опечатки вроде 1000k могут быть легко пойманы). Также проще иметь одно правило для имен переменных и функций, поскольку функции также могут рассматриваться как переменные. Теперь, разумеется, парсеры намного сложнее и мощнее, и у нас есть такие вещи, как пользовательские литералы на C ++. Но в те древние времена предыстории, жертвуя немного ненужной гибкостью, вы могли бы значительно сократить время компиляции (или интерпретации) (и люди все еще жалуются на время компиляции C ++).

И вы можете увидеть эффекты влияния C на весь язык оболочки, поэтому неудивительно, что оболочка Bourne (или оболочка C) и, следовательно, POSIX, ограничила класс разрешенных имен такими же, как у C.

10
ответ дан 24 July 2018 в 17:43
  • 1
    Поскольку объяснения go, это правильный. Это not , что те же соображения применимы ко всем языкам или что оболочки в стиле Бурна имеют синтаксис, аналогичный синтаксису C, но что культура, связанная с C, была сильной, и дизайнеры оболочек должны были придумать некоторые гарантируют, какие идентификаторы будут разрешены. Я думаю, что это могло бы использовать примеры «вы можете увидеть эффекты влияния C во всем языке оболочки», поскольку сходства между ними действительно не превосходят перевесы (подумайте, какие числа считаются истинными , например). Тем не менее, этот ответ правильный. – Eliah Kagan 20 November 2017 в 08:46
  • 2
    @ Eliah, возможно, число вещей также является прямым следствием статусов выхода для успеха и неудачи в C, поэтому я склонен думать об успехах и неудачах вместо истинных и ложных при написании тестов на оболочку. Вы правы в том, что много синтаксиса оболочки не похоже на C, но примеры включают скобки, точки с запятой, короткое замыкание && и ||, отсутствие поддержки ASCII nul в строках, – Olorin 20 November 2017 в 09:41

Другие вопросы по тегам:

Похожие вопросы: