ラグドール
ラグドールのタオがうちに来てから一週間たった。だいぶ調子がでてきた感じ。
ダイエーでたまたま見かけた。誕生日が私と同じだから5か月ほど売れ残っていたことになる。これは運命とか縁とかいうものかね。
Debian sid で sudo apt-get dist-upgrade したら「メジャーバージョン 9.1 はもはや使われません」とか言われたので、素直にアップグレードした。
sudo apt-get install postgresql-9.3
sudo pg_dropcluster 9.3 main --stop
sudo pg_upgradecluster 9.1 main
投稿者
Yoshinori Tahara
時刻:
12:49
0
コメント
ラベル: Postgresql
(ql:quickload :info.read-eval-print.sed)
(ql:quickload :trivial-shell)
(use-package :info.read-eval-print.sed)
(let ((odd-total 0)
(even-total 0))
(with-input-from-string (in (trivial-shell:shell-command "ls -l /tmp"))
(sed (:in in :n t)
(when ($ 5)
(let (($5 (parse-integer ($ 5))))
(if (oddp (parse-integer ($ 2)))
(incf odd-total $5)
(incf even-total $5))))))
(values odd-total even-total))
投稿者
Yoshinori Tahara
時刻:
22:44
0
コメント
ラベル: Common Lisp
Google Reader がなくなってブログ読まなくなったな。それであまり書かなくなった。というわけではない。
今年も鳥取に帰省した。だれもいなく、くらげもいなかった。
Common Lisp 関連は https://github.com/quek/unpyo を書いて遊んでる。
Common Lisp でサーバプログラムを書いている時、エラーは (handler-case ... (error (e) ...) って感じで全てにぎりつぶしたい。
でも、そうすると開発中はデバッガ起動しなくて困る。
どうしよう・・・ということで Hunchentoot のソース読んでみた。 with-simple-restart で invoke-debugger をかこめばいいみたい。
次のようにすると変数1つでデバッガの起動するしないを切り替えられるんだね。
(defvar *invoke-debugger-p* t)
(defun my-debugger (e)
(when *invoke-debugger-p*
(with-simple-restart (continue "Return from here.")
(invoke-debugger e))))
(defmacro with-debugger (&body body)
`(handler-bind ((error #'my-debugger))
,@body))
;; サーバのループ処理イメージ
(loop for socket = (accept)
do (handler-case
(with-debugger (call socket))
(error (e)
(error-handle e))))
*invoke-debugger-p*
を t にしておけばエラー発生時にデバッガがあがる。そのデバッガで Continue リスタートを選べば handler-case により error-handle がちゃんと呼ばれる。
invoke-debugger はそのままだと処理が戻らないから with-simple-restart でかこんであげるってことだね。
投稿者
Yoshinori Tahara
時刻:
11:51
0
コメント
ラベル: Common Lisp
腱鞘炎気味だったのでキー入力をちょっと変えみた。
<
>
がつらい感じだったので
<
>
にしてみた。
;; キー定義。
(set-sequence ((+any+ +no-meta+ +no-shift+ KEY_COMMA) (+any+ +shift+ KEY_9)) ;, → (
((+any+ +shift+ KEY_COMMA) (+any+ KEY_COMMA)) ;shift + , → ,
((+any+ +no-meta+ +no-shift+ KEY_DOT) (+any+ +shift+ KEY_0)) ;. → )
((+any+ +shift+ KEY_DOT) (+any+ KEY_DOT)) ;shift + . → .
((+any+ +shift+ KEY_9) (+any+ +shift+ KEY_COMMA)) ;shift + 9 → <
((+any+ +shift+ KEY_0) (+any+ +shift+ KEY_DOT)) ;shift + 0 → >
((+any+ +meta+ KEY_COMMA) (+any+ +shift+ KEY_COMMA)) ;mata + , → <
((+any+ +meta+ KEY_DOT) (+any+ +shift+ KEY_DOT))) ;mata + . → >
Common Lisp といえばマクロ。マクロのいきつく先といえばコードウォーカー。ということで hu.dwim.walker というコードウォーカ一を使ってみた。
使い方としては次のような感じ。
cl-json を使うと次のように JSON をデコードできる。
(json:decode-json-from-string "{\"a\": 1, \"b\": {\"bb\": 2}, \"c\": 3}")
;;⇒ ((:A . 1) (:B (:BB . 2)) (:C . 3))
これに対する assoc をちまち書きたくないので、シンボル1つで次のように展開されるマクロを書いてみる。
@a ⇒ (ASSOC "A" '((:A . 1) (:B (:BB . 2)) (:C . 3)) :TEST #'STRING-EQUAL)
@b.bb ⇒ (CDR (ASSOC "BB"
(CDR (ASSOC "B" '((:A . 1) (:B (:BB . 2)) (:C . 3)) :TEST #'STRING-EQUAL))
:TEST #'STRING-EQUAL))
これだけなら S式を単純に置換していくだけでも可能だけど
となるとコードウォーカーが必要になる。
ちゃんとしたドキュメントとかないようなので、テストやソースを見ながら書いたのがこれ。
(ql:quickload "hu.dwim.walker")
(ql:quickload "cl-json")
(ql:quickload "split-sequence")
(defun symbol-to-assoc-form (symbol decoded)
(let ((names (split-sequence:split-sequence #\. (subseq (symbol-name symbol) 1))))
(hu.dwim.walker:walk-form
(reduce (lambda (acc x)
`(cdr (assoc ,x ,acc :test #'string-equal)))
names
:initial-value decoded))))
(defun free-and-@-p (form)
(and (typep form 'hu.dwim.walker:free-variable-reference-form)
(char= #\@ (char (symbol-name (hu.dwim.walker:name-of form)) 0))))
(defun walk-with-json-body (decoded form env)
(let* ((walked (hu.dwim.walker:walk-form form
:environment (hu.dwim.walker:make-walk-environment env)))
(walked (hu.dwim.walker:rewrite-ast
walked
(lambda (parent field form)
(declare (ignore parent field))
(if (free-and-@-p form)
(symbol-to-assoc-form (hu.dwim.walker:name-of form) decoded)
form)))))
(hu.dwim.walker:unwalk-form walked)))
(defmacro with-json (json &body body &environment env)
(let ((decoded (gensym)))
`(let ((,decoded (json:decode-json-from-string ,json)))
,@(mapcar (lambda (form)
(walk-with-json-body decoded form env))
body))))
;; @a と @b.bb は json の値 1, 2 に @c は let の 999 になる。
;; with-json がネストしてても問題ない。
(with-json "{\"a\": 1, \"b\": {\"bb\": 2}, \"c\": 3}"
(let ((@c 999))
(list @a @b.bb @c
(with-json "{\"a\": 10, \"b\": {\"bb\": 20}, \"c\": 30}"
(let ((@c 9990))
(list @a @b.bb @c))))))
;;⇒ (1 2 999 (10 20 9990))
投稿者
Yoshinori Tahara
時刻:
18:25
0
コメント
ラベル: Common Lisp