by shigemk2

当面は技術的なことしか書かない

汎変数

setqでは代入値左辺(リストのcar)の書き換えは出来ないが、
この汎変数を書き換えるにはsetqではなくsetfを使う。

;; リストの値の変更
(setq l '(1 2 3))
;; 同じことをsetqでしてもエラー
(ignore-errors (setq (car l) 10))
l					; => (1 2 3)
(setf (car l) 10)
l 					; => (10 2 3)
;; macroexpandでマクロの展開結果を見る
(macroexpand '(setf (car l) 10))	; => (setcar l 10)
(setf (nth 2 l) 30)			; => 30
l					; => (10 2 30)
(macroexpand '(setf (nth 2 l) 30))	; => (setcar (nthcdr 2 l) 30)
;; バッファの書き換えも汎関数で可能
(with-temp-buffer
  (insert "abcdef")
  (buffer-string)			; => "abcdef"
  (ignore-errors (setq (buffer-substring 1 3) "AB"))	; => nil
  (buffer-string)					; => "abcdef"
  (setf (buffer-substring 1 3) "AB")	; => "AB"
  (buffer-string)			; => "ABcdef"
  )
(macroexpand '(setf (point) (point-min))) ; => (goto-char (point-min))
(macroexpand '(setf (current-buffer) "*scratch*")) ; => (set-buffer "*scratch*")
(macroexpand '(setf (point-max) 7))		   ; => (progn (narrow-to-region (point-min) 7) 7)

P196

Emacs Lispテクニックバイブル

Emacs Lispテクニックバイブル