CLでSRFI-29 — #:g1

Posted 2012-01-10 17:21:00 GMT

CLでSRFI、今回は、SRFI-29の「Localizations」です。
SRFI-29は、ローカライズの仕組みで、メッセージバンドル(参照実装ではalist)から言語設定に応じて適切なメッセージを引いてくるという仕組みを提供しています。ついでにformatの拡張もあり。

動作

(let ((translations
       '(((en) . ((time . "Its ~a, ~a.")
                  (goodbye . "Goodbye, ~a.") ))
         ((fr) . ((time . "~1@*~a, c'est ~a.")
                  (goodbye . "Au revoir, ~a.") )))))
  (mapc (lambda (translation)
          (let ((bundle-name (cons 'hello-program (car translation))))
            (if (not (load-bundle! bundle-name))
                (progn
                  (declare-bundle! bundle-name (cdr translation))
                  (store-bundle! bundle-name) ))))
        translations ))

(defun localized-message (message-name &rest args) (apply #'format (cons (localized-template 'hello-program message-name) args)))

(current-language 'en)

(let ((myname "Fred")) (princ (localized-message 'time "12:00" myname)) (terpri)

(princ (localized-message 'goodbye myname)) (terpri) ) ;>> Its 12:00, Fred. ;>> Goodbye, Fred. ;>> ;=> NIL (current-language 'fr)

(let ((myname "Fred")) (princ (localized-message 'time "12:00" myname)) (terpri)

(princ (localized-message 'goodbye myname)) (terpri) ) ;>> Fred, c'est 12:00. ;>> Au revoir, Fred. ;>> ;=> NIL ;;; CL風の~*の拡張 (format "~3@*~A~2@*~A~1@*~A~0@*~A" 1 2 3 4) ;=> "4321"

移植について

SRFI-29は末尾再帰の最適化がされない場合は、スタックが溢れるようなスタイルで書かれているので、そのままCLに持って来た場合、処理系によっては、使い物にならないかもしれません。
SBCLでは、(optimize (debug 1))位で、末尾呼出しの最適化が行なわれるので、それで対処しています。
gotoに書き直すのもの面白いといえば面白いかもしれません。

comments powered by Disqus