SRFI-29は名前の通りローカライズ(localiseのいい訳募集)のためのSRFIです。世の中英語で書いておけば大体OKな風潮ではありますが、エラーメッセージ等の言語を変更したい場合などに使える(かもしれない)ものです。
言語や地域の設定は以下のようにします。
(import (srfi :29)) (current-language) ;; returns current language (e.g. en) (current-language 'fr) ;; sets language to French (current-country) ;; returns current country (e.g. us) (current-country 'nl) ;; sets country to Netherlands (current-locale-details) ;; returns list of details (e.g. (utf-8)) (current-locale-details '(utf-8)) ;; sets details処理系によってはこの辺の情報を環境変数からとってきたりもします。(e.g. Gauche、Sagittarius)
言語ごとにメッセージを設定するには
declare-bundle!を使います。store-bundle!及びload-bundleは可能であればメッセージの設定を永続化及び読み込みを行います。
(let ((translations
'(((en) . ((time . "Its ~a, ~a.")
(goodbye . "Goodbye, ~a.")))
((fr) . ((time . "~1@*~a, c'est ~a.")
(goodbye . "Au revoir, ~a."))))))
(for-each (lambda (translation)
(let ((bundle-name (cons 'hello-program (car translation))))
(if (not (load-bundle! bundle-name))
(begin
(declare-bundle! bundle-name (cdr translation))
(store-bundle! bundle-name)))))
translations))
上記はSRFIの例からですが、load-bundleでbundle-name(この場合はhello-program)の読み込みを試み、失敗すればdeclare-bundle!で設定、store-bundle!で永続化を試みます。実際に設定されたメッセージを取得するにはlocalized-templateを使います。このSRFIではformatの拡張も定義されていて、
~[n]@*でn番目に与えられた引数を参照します。例えば以下のような手続きを定義します(SRFIの例です)
(define localized-message
(lambda (message-name . args)
(apply format (cons (localized-template 'hello-program
message-name)
args))))
(let ((myname "Fred"))
(display (localized-message 'time "12:00" myname))
(display #\newline)
(display (localized-message 'goodbye myname))
(display #\newline))
;; If current language is 'fr' then
;; prints 'Fred, c'est 12:00.'
;; and 'Au revoir, Fred.'
多少端折った説明になったのは僕自身はこのSRFIを使っていないので、今一使いどころを把握していないからなのですが、まぁ、こういうものだという部分は伝えられたかと思います。今回はSRFI-29を紹介しました。
No comments:
Post a Comment