ハッシュテーブルのファイルへの書き出しとか

どもです。
さっぶいですねー。


ハッシュテーブルをファイルをファイルに保存しておきたいなーなんて思っちゃったりいたしまして,
さてどうしたもんかと。
以前,確かハッシュテーブルはファイルにそのまま書き出せないみたいなのを
どっかで読んだ記憶がありまして,適当にprintで書き出して試して見たらやっぱりダメでした。
つまりコレがnilを返すわけです。

(let ((tbl (make-hash-table :test #'equal))
      (tbl2 nil))
  (puthash "key1" (make-hash-table :test #'equal) tbl)
  (with-temp-buffer
    (goto-char (point-min))
    (print tbl) ; prin1でも別にいい
    (goto-char (point-min))
    (setq tbl2 (read (current-buffer))))
  (hash-table-p tbl2))

結論から言うと,後々わかったんですがこれで可能。
最初に試したときに,なぜかこれがnilを返していて,
もしくは何かを間違っていてnilを返したと勘違いして,
せこせこと書き出し用の関数を作りました。


なぜに読み込めなかったのか,今となっては謎なのですが,
似たようなことを別のelispでやっているはずだと思い出しそのファイルを覗いたところ,
書き出しはそのままテーブルをprin1。読み込みはread。
えー。犯人は間違いなくワタシ。しかし犯人はやった覚えはないと容疑を否認している模様。
んなあほな。ほんまに記憶ないよ。


ちょっとぐぐっとググってみると,どうやらemacs23くらいから可能になったようです。
http://www.emacswiki.org/emacs/ElispCookbook からちょいと拝借すると,

 (read (prin1-to-string (make-hash-table))) ;; Error before Emacs 23.
    ==> #s(hash-table size 65 test eql rehash-size 1.5 [...] data ())

らしいです。


ただしでかいハッシュテーブルの場合,ごりっと書き出すのと,
走査しながら書き出すのとではどっちが速いかはわかりません。
いやごりっと書き出す方が速いだろ,そりゃ。
でもたぶんハッシュの値の型とでかさによると思うなーと負け惜しみを言っておこう。
1行がめーーっちゃ長くなるような場合は読み込み遅くなりそうじゃん?
ぐちぐち。
だってall of my efforts went in vainなんだもん。
あ,いや,そうそう,下位互換性を持たせたかったんですよ! まじで。
はじめからわかってたし。はいチャックチャック。

まとめ

ハッシュテーブルの書き出し,読み込みのお供にはprin1とreadをどうぞ。