Hatena::Groupemacs

poginの日記 このページをアンテナに追加 RSSフィード

2011-10-05

fboundpとboundpの違い

| 02:59 | fboundpとboundpの違い - poginの日記 を含むブックマーク はてなブックマーク - fboundpとboundpの違い - poginの日記 fboundpとboundpの違い - poginの日記 のブックマークコメント

Emacsで fboundp と boundp という関数があるのだけれど、一体何の違いがあるかがよくわからなかった。調べてみるとなんかわかった気がするのでメモしておく。

使い方

fboundpはシンボルが関数として束縛があるかどうか。束縛されている場合は t を返し、そうでない場合 nil を返す。

(fboundp 'foo)
;=> nil
(defun foo ()
  nil)
;=> foo
(fboundp 'foo)
;=> t

boundpはシンボルが変数として束縛されているかどうか。束縛されている場合 t を返し、そう出会い場合 nil を返す。

(boundp 'bar)
;=> nil
(setq bar 1)
;=> bar
(boundp 'bar)
;=> t

例1、elscreen-modeがある場合とない場合の処理を書きたい場合

(defun func-hoge ()
  (if (fboundp 'elscreen-mode)
      (insert "tです\n")     ;; 束縛されている場合の何かの処理    then節
    (insert "nilです\n"))    ;; 束縛されていない場合の何かの処理  else節
  )
(func-hoge)
;=> tです
; nil

(defun func-arg-hoge (func)
  (if (fboundp (eval 'func))
      (insert "tです\n")
    (insert "nilです\n")))
(func-arg-hoge 'elscreen-mode)
;=> tです
; nil

例2、変数が束縛されているか、いないかの処理を書き分けたい場合

(setq piyo "piyo")

(defun var-piyo ()
  (if (boundp 'piyo)
      (insert "tです\n")     ;; 束縛されている場合の何かの処理    then節
    (insert "nilです\n"))    ;; 束縛されていない場合の何かの処理  else節
  )
(var-piyo)
;=> tです
; nil
(defun var-arg-piyo (var)
  (if (boundp (eval 'var))
      (insert "tです\n")
    (insert "nilです\n")))
(var-arg-hoge 'piyo)
;=> tです
; nil

詳細

シンボルには4つのセルというものを持っている。

表示名セルシンボルの名前(文字列)
値セル変数の値
関数セル関数定義
属性リストセル属性リスト

この内、fboundpは関数セルの束縛状態を返し

boundpは値セルの束縛状態を返す。

7.1 シンボルの構成要素

関数が定義されていない場合、そのシンボルの関数セルは空(void)である。

変数が定義されていない場合、そのシンボルの値セルは空(void)である。

定義されていない関数を評価した場合

(func-hoge) 
;=> Lisp error: (void-function func-hoge)

定義されていない変数を評価した場合

var-hoge
;=> Lisp error: (void-variable var-hoge)

とこのようになる。

関数や変数を定義するためには束縛をしなければ使うことができない。

関数を束縛するためには例えばこのように定義する。

;; 関数の定義
(defun func-hoge ()
  "define func-hoge")
;=> func-hoge

(func-hoge)
;=> "define func"

変数を束縛するにはsetq、defvar、defconstなどを使う。

;; 変数の定義
(setq hoge 1)
;=> 1
hoge
;=> 1

(setf piyo 2)
;=> 2
piyo
;=> 2


(defvar foo 3)
;=> foo
foo
;=> 3

(defconst bar 4)
;=> bar
bar
;=> 4

感想

今までEmacsの仕様をここまでちゃんと調べることがなかったのでいい機会になった。

Lispで扱うものはシンボルというものだったのをすっかり忘れた。

この話題について書こうと思って書いたらかなりの時間を使ってしまったのが痛いorz。もっと速く書けるようになりたいもんだなぁと思う。でもちゃんと記事を完成させたので一歩前進だなと。

参考リンク

@see fboundp - refwiki

@see boundp - refwiki

@see 5.3.4 fboundp

@see 10.4 変数が『空』であるとき

@see 11.8 関数セルの内容の参照

@see 7.1 シンボルの構成要素

@see 11.3 関数を命名する

>>>> 2012/1/25 fboundpとboundpの例で、nilの場合のコードがなかったので追加

>>>> 2012/3/9 関数、変数の定義の仕方のコードを追加

MiriamMiriam2012/02/20 00:05THX that's a great aswner!

ToshikazuToshikazu2013/12/21 18:25It's much easier to unsrtdeand when you put it that way!

AnderAnder2013/12/23 01:32Kewl you should come up with that. <a href="http://jfnzvlxjlwb.com">Exeellcnt!</a>