signal 20160816.738(in MELPA)
Advanced hook

概要

昨日はsignal.elのフックとの類似性を示し ました。
今日はフックとの違いを示します。

おさらいすると、hookとsignalの対応関係は以下のようになっています。

定義 defvar(defcustom) defsignal
呼び出し run-hooks signal-emitb
追加 add-hook signal-connect
削除 remove-hook signal-disconnect

この表を見てわかるように、 run-hooks に対応するのが signal-emitb ですね。
ところでemitbとは何なのかと疑問に思わなかったでしょうか?
emitとは発行するという意味ですが、emitbという英単語は存在しません。
ではこのbとは何でしょうか?

答えばblockingのbです。

run-hooks実行中はフックが実行されているように、signal-emitb実行中はsignal関数(worker)が実行されています。
hook/signal実行中はそれらが実行されていて、次の処理をブロックしているのです。

対してnon-blockingなsignal実行関数が signal-emit です。
この関数は「signalを発行したよ。実行は後で任せた」という関数です。

そのココロは
タイマー関数でsignal-emitbを呼んでいる
ことになります。

インストール

パッケージシステムを初めて使う人は
以下の設定を ~/.emacs.d/init.el の
先頭に加えてください。

(package-initialize)
(setq package-archives
      '(("gnu" . "http://elpa.gnu.org/packages/")
        ("melpa" . "http://melpa.org/packages/")
        ("org" . "http://orgmode.org/elpa/")))

初めてsignalを使う方は
以下のコマンドを実行します。

M-x package-install signal

アップグレードする方は、
以下のコマンドでアップグレードしてください。
そのためにはpackage-utilsパッケージが必要です。

M-x package-install package-utils (初めてアップグレードする場合のみ)
M-x package-utils-upgrade-by-name signal

実行例

(require 'signal)
(defsignal my-signal)

(defvar x nil)
(signal-connect :signal 'my-signal
                :worker 'set
                ;; デフォルトの引数も指定できる
                :arg (list 'x "<I am emitted.>"))
(progn
  ;; すぐにsignalを発行する
  (signal-emitb 'my-signal)
  x)                       ; => "<I am emitted.>"
(setq x nil)
(progn
  ;; フォーム実行後にsignalを発行する
  (signal-emit 'my-signal)
  ;; フォーム実行後0.3秒後にsignalを発行する。引数も変更する
  (signal-emit 'my-signal :arg (list 'x "<emitted again>") :delay 0.3)
  x)                       ; => nil
;;; 0.1秒待つとsignalが発行されている
(sit-for 0.1)
x                                       ; => "<I am emitted.>"
;;; さらに0.3秒待つと次のsignalも発行されている
(sit-for 0.3)
x                                       ; => "<emitted again>"
;;; 後片付け
(run-at-time 1 nil 'signal-disconnect 'my-signal 'princ)


本日もお読みいただき、ありがとうございました。参考になれば嬉しいです。