Created
August 15, 2023 23:46
-
-
Save ROCKTAKEY/f0cd1b21a383ba567624d680790475b1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (require 'cl-lib) ; `cl-letf', `cl-flet' | |
| (require 'cl) ; `flet' | |
| (defun func1 () | |
| "`original'というシンボルを返すだけの関数。" | |
| 'original) | |
| (defun print-func1 () | |
| "`func1'を呼び出したときの返り値を表示する関数。" | |
| (message "%s" (func1))) | |
| (defun modify-func1-by-flet () | |
| "`flet'を使って`func1'を上書きした上で`print-func1'を実行。 | |
| `flet'は中で呼び出した`print-func1'においても`func1'を変更する。 | |
| `flet'での束縛では、外側で束縛すると内側の全てに波及し、 | |
| そのスコープを出ていけばなにもなかったことになる。このような挙動は動的束縛、 | |
| dynamic bindingと呼ぶ。 | |
| " | |
| (flet ((func1 () 'modified)) | |
| (print-func1))) | |
| (modify-func1-by-flet) ; modified | |
| (defun modify-func1-by-cl-flet () | |
| "`cl-flet'を使って`func1'を上書きした上で`print-func1'を実行。 | |
| `flet'は中で呼び出した`print-func1'においては`func1'を変更しない。 | |
| なお、`cl-flet'の中で`func1'を直接呼び出せば上書き済みのものとなる。 | |
| このように字句通りにしか値を読み出さない挙動から、このような変数や関数の束縛を字句的束縛、 | |
| lexical bindingと呼ぶ。" | |
| (cl-flet ((func1 () 'modified)) | |
| (print-func1))) | |
| (modify-func1-by-cl-flet) ; original | |
| (defun modify-func1-by-cl-flet () | |
| "`cl-letf'を使って`func1'を上書きした上で`print-func1'を実行。 | |
| `cl-letf'は中で呼び出した`print-func1'においても`func1'を変更する。 | |
| `cl-letf'は`flet'と同様に動的束縛を行う。 | |
| ただし、関数に限らず、変数や、変数の一部分など様々なもの(ジェネリック変数と呼ばれる)を動的束縛できる。 | |
| 変数の場合は通常の`let'のように使える。 | |
| ジェネリック変数については以下を参照。 | |
| https://ayatakesi.github.io/lispref/28.2/elisp-ja.html#Setting-Generalized-Variables" | |
| (cl-letf (((symbol-function 'func1) (lambda () 'modified))) | |
| (print-func1))) | |
| (modify-func1-by-cl-flet) ; modified |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment