숫자 함수 이름이 허용되지 않는 이유는 무엇입니까?


10

다음을 고려하세요:

$ 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있는 것은위한 shorthands 것 true하고 false, 그러나 당신이 볼 수 있듯이 나는 기능에 숫자 이름을 사용하여 문제를 다 퉜다. 별명 및 두 자리 이름에서도 동일한 동작이 발생합니다.

질문은 "왜"입니까? POSIX가 의무화합니까? 아니면 그냥 본 같은 껍질?

질문과 관련된 질문 도 참조하십시오 .


1
posix가 요구하는 것은 대부분 Bourne과 같은 껍질입니다. : P
muru

난 당신이 무슨 짓을했는지 참조 . . . > :) lol
Sergiy Kolodyazhnyy 1

4
@fkraiem를 참조하십시오 meta.askubuntu.com/q/13807/295286 / 쉘 스크립트는 항상 우분투 질문 : 그것은 어떤 우분투 시스템의 적절한 시스템 관리에 필수적인 항목의에 주제에왔다 쉘
세르지 Kolodyazhnyy

4
그 지적이의 가치는 0이다 true쉘 스크립트와 1false이 인식하지 못하는 읽는 경우 사람에 (정말, 0이 아닌 거짓으로 처리됩니다). 이것은 대부분의 다른 프로그래밍 언어와는 다릅니다.
Ethan Kaminski

2
@EthanKaminski yep 는 명령의 종료 상태 까지는 절대적으로 사실입니다. true쉘 에 0의 리턴 값이 있습니다. 그러나 산술 확장에서 $((...))반환 상태는 1로 바뀌고 true0은 falseC 언어 구문과 일치합니다. 예를 들어보십시오. bash -c 'echo $((1==1));echo $((1==2))' 이 질문 이외의 일을하려는 것은 실제로 행동을 "반전"하는 것이 었습니다. 내가 정확히 무엇을하려고했는지 보려면 여기 에 대한 대답의 마지막 예 를 참조하십시오. 어리석은 생각이지만 그럼에도 불구하고 효과가 있습니다
Sergiy Kolodyazhnyy

답변:


14

POSIX의 말 :

2.9.5 기능 정의 명령

함수는 새로운 위치 매개 변수를 사용하여 복합 명령을 호출하기위한 간단한 명령으로 사용되는 사용자 정의 이름입니다. 기능은 "기능 정의 명령"으로 정의됩니다.

함수 정의 명령의 형식은 다음과 같습니다.

 fname ( ) compound-command [io-redirect ...]

함수 이름은 fname입니다 . 응용 프로그램은 이름 (XBD 이름 참조 )이고 특수 내장 유틸리티의 이름이 아닌지 확인해야합니다. 구현시 함수 이름의 다른 문자를 확장명으로 사용할 수 있습니다. 구현은 함수와 변수에 대해 별도의 네임 스페이스를 유지해야합니다.

과:

3.235 이름

쉘 명령 언어에서 휴대용 문자 집합의 밑줄, 숫자 및 알파벳으로 만 구성된 단어입니다. 이름의 첫 문자는 숫자가 아닙니다.

참고 : 휴대용 문자 세트는 휴대용 문자 세트에 자세히 정의되어 있습니다.

따라서 숫자로 시작하는 단어는 함수 이름이 될 수 없습니다.


아직도 POSIX는 그 이유를 정확히 말하지는 않지만 "표준 때문에"답변으로 삼겠습니다. 감사합니다
Sergiy Kolodyazhnyy

4
@SergiyKolodyazhnyy 나는 그것이 상속 된 것이라고 말하고 싶습니다. 이 이름에 대한 표준은 다른 것들에서도 상당히 일반적이므로 (IIRC C 이름도 같은 표준을 따릅니다) 아마도 유닉스 일 것입니다. 또한 C에서는 구문 분석하기가 더 쉽습니다.
muru

3
C의 @muru는 그것이 허용된다면 약간의 모호성을 가져올 것입니다. 예를 들어 무엇을 1L의미합니까? 기능 명? 아니면 long int리터럴?
Ruslan

2
또한 C에서는 베어 함수 이름이 해당 함수에 대한 포인터 역할을 할 수 있습니다. 이를 통해 함수에 매개 변수로 함수를 전달하고 변수에 대한 참조를 변수 등에 저장할 수 있습니다. 콜백에 자주 사용됩니다. 이것은 함수의 이름 다음에 ()인수 가 붙은 인수와 대조적으로 해당 함수에 대한 호출을 나타내며 호출되는 함수에 의해 반환되는 값을 취합니다. 따라서 int f() { return 42; }C에 함수가 있으면 f포인터 컨텍스트에서 유효하고 포인터 f()가 아닌 정수 컨텍스트에서 유효합니다.
CVn

13

이는 수학 연산과 변수 또는 함수 또는 메소드 간의 혼동을 방지하기 위해 여러 언어의 표준입니다.

치다:

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

보시다시피, 숫자가 변수 또는 함수 이름으로 허용 된 경우 프로그램에서 나중에 수학을 수행하는 것은 매우 혼란 스러울 수 있으며 나중에 실제로 해당 숫자로 수학을 수행해야하는 경우 창의적인 해결 방법을 찾아야합니다. 일부 언어에서는 예기치 않은 결과가 발생할 수도 있습니다. 루프의 숫자를 늘리고 있지만 숫자 중 하나가 이미 문자열과 같은 변수라고 가정합니다. 즉시 오류가 발생합니다. 코드의 원래 작성자가 아닌 경우 해당 오류를 찾는 데 시간이 오래 걸릴 수 있습니다.

간단히 말해서, 대부분의 언어에서 숫자를 변수, 함수 또는 메소드 등의 이름으로 사용할 수없는 이유입니다.


나는 "그러나 쉘에서 변수 $가 확장되기 위해 앞에 붙일 필요가있다"고 언급하려고 했지만, 쉘이 다른 언어에서 영감을 받았다면 다시 말하지만, 산술 확장 ((변수에는 선행이 필요하지 않습니다 $. 좋아, 나는 이해할 수있다
Sergiy Kolodyazhnyy

3
예, 거의 모든 언어로 예기치 않은 결과가 발생하기 때문에 규칙이지만, 작동하는 상황에서도 코드 후에 작업 해야하는 사람에게는 코드를 이해하기가 매우 어려울 수 있습니다.
Josh

2
@SergiyKolodyazhnyy 산술 확장을 통해 변수 이름을 참조하지 않고 참조 할 수 있습니다 $. 하지만 그건 "그냥 일반적인 규칙을 다음과 같은"다른 이유는 아마 차의
홉스

@ hobbs 네, 절대적으로 동의합니다
Sergiy Kolodyazhnyy

1
이 "대부분의 언어"설명은 셸에는 의미가 없습니다. 모든 Bourne의 스타일 쉘은 이름이 매개 변수가 같이 숫자 리터럴 또는 운영자 : 0쉘 또는 스크립트 이름에 대한, 1, 2, ..., 위치 매개 변수에 대한, *그들에게 합류를 들어, -사용 가능 옵션, ?마지막 출구 상태 및 !에 대한 가장 최근의 비동기 작업 PID (따라서,도에서 $(( ))의이 $종종 필요합니다.) 제안 된 근거를 입증하기 위해 여기에 표시된 코드는 어떤 Bourne의 스타일 쉘 스크립트 아니라, 그런 식으로 설명 할 수있는 방법이 없기 때문에,로 가 적용되지 않습니다 에 그들.
Eliah Kagan

10

C에서는 다음과 같은 표현을 고려하십시오.

1000l + 2.0f;

1000l변수 인가 상수인가? 변수 이름은 숫자로 시작할 수 없으므로 상수 여야합니다. 이렇게하면 구문 분석이 더 쉽고 엄격 해집니다 (예 : 오타 1000k가 쉽게 잡힐 수 있음). 함수도 변수로 취급 될 수 있으므로 변수 및 함수 이름에 대한 단일 규칙을 갖는 것이 더 쉽습니다. 지금은 물론, 파서는 훨씬 더 복잡하고 강력한, 우리는 C ++에서 사용자 정의 리터럴 같은 것들이 있습니다. 그러나 고대 선사 시대로 돌아가서 약간의 불필요한 유연성을 희생하면 컴파일 (또는 해석) 시간이 훨씬 짧아 질 수 있습니다 (그리고 사람들은 여전히 ​​C ++ 컴파일 시간에 대해 불평합니다).

쉘 언어 전체에서 C의 영향을 볼 수 있으므로 Bourne 쉘 (또는 C 쉘)과 POSIX가 허용되는 이름의 클래스를 C의 클래스와 동일하게 제한 한 것은 놀라운 일이 아닙니다.


2
으로 설명은 이동이 올바른 것입니다. 그건 하지 같은 고려 사항이 C와 유사한 구문이 Bourne의 스타일 쉘 모든 언어로 또는 적용하지만 C와 관련된 문화는 강한 쉘 디자이너 마련했다는 것을 일부 식별자가 될 것입니다 무엇으로 보장 허용됩니다. 나는 이것이 "쉘 언어 전체에 걸쳐 C 영향의 영향을 볼 수있다"는 예를 사용할 수 있다고 생각한다. 왜냐하면 그것들 사이의 유사성은 실제로 차이를 능가 하지 않기 때문이다 ( 예를 들어 어떤 숫자가 으로 간주되는지에 대해 생각하라 ). 그럼에도 불구하고이 답변은 맞습니다.
엘리아 카간

@Eliah는 아마도 숫자 문제는 C에서의 성공과 실패에 대한 종료 상태의 직접적인 결과이기 때문에 쉘 테스트를 작성할 때 성공과 실패의 관점에서 참과 거짓 대신 생각하는 경향이 있습니다. 셸 구문은 C와 다를 바가 없지만 괄호, 세미콜론, 단락 &&||문자열의 ASCII
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.