이제는 귀찮다. yes/no 대신 y/n을 쓰자
(defalias 'yes-or-no-p 'y-or-n-p)
shell 종료를 하려니 물어본다. yes/no. 단어를 전부 쳐넣어야 하네. 귀찮다. y/n으로 바꾸자.
yes/no
상대적으로 중요한 동작일 경우 단어 전체를 넣도록 유도한 것 같다. 뉴비일 때는 꼬박꼬박 쳐넣었지만, 이제는 귀찮다. 좀 썼잖아? 쉽게 가자.
-p
yes-or-no-p
. 끝에 -p
가 붙었다. elisp에선 술어(predicate)에 -p
를 붙이는 게 코딩 관례(Coding Conventions).
fset, defalias
많이 바꾼다. 어디 귀찮은 게 나 뿐이랴. 그래서 yes-or-no-p
에 관련글을 쉽게 찾을 수 있다. 찾다보면 사용함수가 두 가지인 걸 발견할 수 있다. 어떤 곳은 fset
을 사용하고 다른 곳은 defalias
를 사용한다.
함수 이름만 보면 별칭을 만들고 싶은 거라 fset
보다는 defalias
가 적합해 보인다.
defalias
를 사용하면 뭐가 다른가? 히스토리를 기록하는 게 다르다. unload-feature
를 통해 되돌릴 수 있는 기능을 제공한다.
그래서 사용하는 입장에선 defalias
를 피처(feature)에 사용하는게 아니라면 fset
과 별 차이가 없다.
defalias와 피처(feature)
피처는 함수와 변수 컬렉션을 의미한다. 단위는 파일. 파일에서 반 쪼개서 피처 반반 이런 거 안 된다.
;;; my-alias.el
(provide 'my-alias)
(defalias 'yes-or-no-p 'y-or-n-p)
(defalias 'sh 'shell)
my-alias라는 피처를 만들어서 편하게 치고 싶은 심볼을 정의한다. 여기서 yes-or-no-p는 emacs에서 할래 말래 물어볼 때, 사용하는 심볼이다. 반면 sh는 새롭게 정의하는 심볼.
;;; init.el
(add-to-list 'load-path "~/.emacs.d/")
(require 'my-alias)
load-path에 추가가 안 됐다면 추가해주고 require로 로드한다. require는 인자로 넘기는 피처가 로드됐는지 확인해서 그냥 편하게 사용하면 된다.
(featurep 'my-alias)
(member 'my-alias features) ;; or
둘 중 하나로 피처가 로드됐는지 확인할 수 있다.
(symbol-function 'yes-or-no-p)
;;=> y-or-n-p
(symbol-function 'sh)
;;=> shell
symbol-function으로 function cell에 있는 오브젝트를 확인할 수 있다. 리턴 값을 보니 alias가 제대로 설정됐다.
(unload-feature 'my-alias 'FORCE)
피처를 언로드한다. init.el에 정의해 종속성이 걸려 FORCE
를 빼면 실패한다.
(featurep 'my-alias)
;;=> nil
(symbol-function 'sh)
;;-> symbol's function definition is void
(symbol-function 'yes-or-no-p)
;;-> symbol's function definition is void
피처를 언로드하면 피처 안에서 defalias로 정의한 심볼이 싹 제거된다. 히스토리 기록이라길래 이전 함수 정의를 복원시키는 줄 알았다. 하지만 아니네. 그냥 함수 정의를 날려버린다. emacs에서 기본으로 정의하는 yes-or-no-p
가 날아갔다.
참고
C-x C-s C-x C-c