schemeで変数名を式で。データファイル処理
schemeでset!の第1引き数を式にしたい。
もちろん、シンボル、あるいは変数名を返すもの。
perlで言うと、例えば、
@arry = ('foo','bar','baz','qux','quux'); for($i = 0; $i <5; ++$i){ ${ $arry[$i] } = $i; } print $foo , "\n"; print $bar , "\n"; print $baz , "\n"; print $qux , "\n"; print $quux , "\n";
こんな感じに使えるような。
なんでかと言うと、Javaでいう.propertiesファイルとか、YAMLとかjsonとかいう「key=value」形式的なデータファイルを、schemeで処理したい。
xmlほどのものじゃなく。
これはそもそもS式を使え、ということなんだろう。
で、
(prof-dir "~/Application Data/Mozilla/Firefox/Profiles/xxxxxxx") (user-agent "Mozilla/5.0 (Windows; U; Windows NT 5.1; ja-JP)") (blog_id "1111111")
という平たいペアのリストをreadで読み込んで、対応する変数にset!する。
(use file.util) (define ldb-data "ldb-data.scm") (define prof-dir #f) (define user-agent #f) (define blog_id #f) (call-with-input-file (build-path (current-directory) ldb-data) (lambda (inp) (let loop ((sexp (read inp))) (unless (eof-object? sexp) (case (list-ref sexp 0) ((prof-dir) (set! prof-dir (list-ref sexp 1))) ((user-agent) (set! user-agent (list-ref sexp 1))) ((blog_id) (set! blog_id (list-ref sexp 1))) (else 'ERROR)) (loop (read inp))))))
これだと、変数が増えると、その分caseのパターンが増えていく。
そこで、ちょっと変える
(call-with-input-file (build-path (current-directory) ldb-data) (lambda (inp) (let loop ((sexp (read inp))) (unless (eof-object? sexp) (eval `(set! ,(list-ref sexp 0) ,(list-ref sexp 1)) (interaction-environment)) (loop (read inp))))))
準クォートとevalを使ってみたけど、なんか持って回ったやり方に見える。
素直に、
(set! prof-dir "~/Application Data/Mozilla/Firefox/Profiles/xxxxxxx")
という形で書いたデータファイルにしたほうがいいんだろうか。