답변:
주요 함정에 대한 바인딩을 의미한다는 것입니다 정의되지 않은 변수 - 즉 변수가 정의되지 defvar
친구들-변화 lexical-binding
없이, : let
바인딩의 모든 동적으로하지만, 함께 lexical-binding
활성화 정의되지 않은 변수 바인딩 어휘 , 심지어 현재 어휘 범위 완전히 사용하지 않는 경우 생략 .
오래된 코드는 때때로 이것에 의존합니다. 선택적 기능에 대한 엄격한 종속성을 피하기 위해 해당 라이브러리가 필요 하지 않거나 변수 자체를 선언 하지 않고 동적 변수 를 바인딩 합니다.
(let ((cook-eggs-enabled t))
(cook-my-meal))
쿠킹 기능이 옵션 인 경우, 사용자에게 불필요한 의존성을 강요하고 싶지 않으므로 함수를 사용하지 않고 (require 'cook)
대신 자동 로딩에 의존 cook-my-meal
합니다.
인간 독자 cook-eggs-enabled
에게는 지역 변수가 아니지만 여전히 cook
라이브러리의 전역 동적 변수를 참조하는 것이 분명 합니다. lexical-binding
이 코드가 없으면 의도 한대로 작동 cook-eggs-enabled
합니다. 정의 여부에 관계없이 동적으로 바인딩됩니다.
로 lexical-binding
: 그러나, 휴식 cook-eggs-enabled
이제 바인딩 어휘 (사용하지 않을 있기 때문에 멀리하고 최적화) 글로벌 동적 변수가 있도록 cook-eggs-enabled
되어 있지 지금까지 여전히 전혀 감동과 nil
시간에 의해 cook-my-meal
이라고 우리는 놀라 울 정도로 어떤 달걀이되지 않도록, 우리의 식사에서.
운 좋게도 이러한 문제는 쉽게 발견 할 수 있습니다 . 바이트 컴파일러는 자연스럽게 사용되지 않는 어휘 바인딩에 대해 경고 합니다.
해결 방법은 간단합니다. (require 'cook)
(어쨌든 선택 사항이 아닌 기능의 경우)를 추가 하거나 어려운 종속성을 피하기 위해 변수 를 자신의 코드에서 동적 변수로 선언하십시오 . 이에 대한 특별한 defvar
형식이 있습니다.
(defvar cook-eggs-enabled)
이것은 cook-eggs-enabled
동적 변수로 정의 되지만 변수 의 바인딩 특성을 제외하고 docstring, load-history
(및 따라서 find-variable
친구) 또는 다른 것에 영향을 미치지 않습니다 .
cook-eggs-enabled
할 수 언 바운드 때let
완료? 나는 전에 이와 같은 버그가 발생했다고 확신합니다. defvar은 내부에서 발생let
했으며let
나중에 변수를 초기 (void) 상태로 복원했습니다.