define-keyについて混乱を招くもの(および引数をいつ引用するかという問題)

StackOverflow https://stackoverflow.com/questions/1636336

  •  06-07-2019
  •  | 
  •  

質問

define-keyを使用する場合、KEYMAPを引用することは想定されていないようです。

(define-key org-remember-mode-map "\C-c\C-r" 'org-remember-kill)

引用されていない関数のすべての引数が評価され、ヘルプによると、define-keyはマクロではなく関数であると思うため、混乱しています。 define-keyの呼び出し後にKEYMAPの値を変更できる理由がわかりません。

(defun increment-value (a)
  (setq a (+ 1 a)))

(setq my-num 10)

(increment-value my-num)

my-num ; ===> 10

更新:答えはすべてを説明しますが、まだ混乱している人のために、さらに例を挙げて説明します。

上記の増分値の例はこれと同等です:

(let ((n 0))
  (print n) ; prints 0
  (let ((a n))
    (setq a (+ 1 a))
    (print a) ; prints 1
    )
  (print n) ; prints 0
  )

上で起こっていることは、このマップの例で起こっていることと似ていると思います:

(let ((some-map '(1 2)))
  (print some-map) ; prints (1 2)
  (let ((a some-map))
    (setq a (list 4 (second a)))
    (print a) ; prints (4 2)
    )
  (print some-map) ; prints (1 2)
  )

define-keyで行われていることは、この2番目のsome-mapの例に似ています:

(let ((some-map '(1 2)))
  (print some-map) ; prints (1 2)
  (let ((a some-map))
    (setcar a 4)
    (print a) ; prints (4 2)
    )
  (print some-map) ; prints (4 2)
  )

これら3つの例を念頭に置いて回答をもう一度読んでください。 http://www.emacswiki.org/emacs/ListModification

もお読みください。
役に立ちましたか?

解決

実際には 'org-remember-map を変更するのではなく(特定のリスト構造へのポインター)、実際の構造を変更します。変更の詳細については、この情報ページをご覧ください。リスト。

特に、 'make-keymap のドキュメントを見ると:

  

(make-keymap& optional string)

     

の新しいキーマップを構築して返します   フォーム(キーマップCHARTABLE。ALIST)。   CHARTABLEは保持する文字テーブルです   すべてのキャラクターのバインディング   修飾子なし。その中のすべてのエントリ   最初はnilで、"コマンドを意味します   未定義"。 ALISTは連想リストです   関数のバインディングを保持します   キー、マウスイベント、その他   入力に現れるもの   ストリーム。最初は、ALISTはnilです。

キーマップは3つの要素を持つリストであることがわかります。それを描いてみましょう(yay M-xアーティストモード):

 org-remember-map
    |
    |
    v
 +----+----+    +----+----+
 | |  |  --+--->+  / | \  |
 +-+--+----+    +-/--+--\-+
   |              |     |
   v              v     v
keymap      CHARTABLE  ALIST

つまり、 'org-remember-map の値は上記の構造のようなものであり、キーを定義するとき、あなたがしていることは、 ALIST 構造のblob部分。

他のヒント

値と名前と値のマッピングが混乱しています。

増分値関数では、名前 a の新しい値へのマッピングを変更するほど a の値は変更しません。

基本的に、10の値を変更する方法はありません。10は10です!

ただし、最初のケースでは、名前 org-remember-mode-map のマッピングを完全に異なるマップに変更(新しい値を設定)するか、その名前(現在の値)が指すマップを変更します。これがdefine-keyの機能です。

図:

(setq a '(1 2)) -> (1 2)
(setcar a 4) -> 4
a -> (4 2)

あなたが書くものはすべて完全に正しいです。欠けているのは、リスト(キーマップはリストとして表される)は値そのものではなく、値のコンテナーであるということです。したがって、リストを関数に渡して、その関数にリストの値を変更させることができますが、持っているリストは同じリストのままです。

詳細はすべて Cons elispマニュアルのCell Type セクション。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top