在程式中通常有若干種方法將資訊串成字串,一些可能的寫法如:

msg = format("Do you want to delete %s from %s?", user.name, group.name);

msg = "Do you want to delete {1} from {2}?".format(user.name, group.name);

msg = "Do you want to delete " + user.name + " from " + group.name + "?";

msg << "Do you want to delete " << user.name << " from " << group.name << "?";

對於多數應用來說,以上並沒有其中一個做法比其他具備壓倒性優勢,所以在使用上有很大程度取決於個人喜好。有些比較具有經驗的人可能會覺得 formatter 風格比較容易閱讀,不過當插入的資料太多時一樣會造成畫面破碎,而且資料和插入位置不容易對起來。

最近在解決一個問題,發現一個 formatter 明顯優於串接風格的地方。這裡先假設我們有一個叫做 _tr(str) 的函數或巨集, 可將將 str 轉換至目前語系對應的字串,許多程式語言或者 framework 都有類似的基礎設施。將上面的例子加上翻譯大概像這樣:

msg = format(_tr("Do you want to delete %s from %s?"), user.name, group.name);

msg = format(_tr("Do you want to delete {1} from {2}?"), user.name, group.name);

msg = _tr("Do you want to delete ") + user.name + _tr(" from ") + group.name + "?";

程式設計者應該會立刻發現,在串接形式中 _tr 被使用了比較多次,因而可能有較高的成本,不過現實中這些成本是微不足道的。翻譯人員大概不會注意到這點,他們比較在意的是收到的是一堆支離破碎的文字片段,這是因為開發者一般會使用自動化工具建立翻譯清單,串接形式往往會造成程式裡的一句話會被肢解開來,落在翻譯清單的不同位置。

所以翻譯人員看到 "is broken" 時,心裡會想:「這要翻譯成『損毀』嗎?」直到他們對照 UI 找到原句是「The connection to OOXX is broken.」,了解到「斷線」應該比「損毀」更接近實況。

不過這些都還是無足道哉的小事,其實真正棘手的地方其實是文法。串接式寫法限制了文字片段在句子中出現的順序,然而現實中不同語言有不同的詞序規則。我們都知道英文和中文句型有些許的差異,以上面的例子來說:

Do you want to delete
你是否要刪除

from
從

我想沒有幾個以中文為母語的人覺得「你是否要刪除小黃從同學」這樣的句子很自然。反觀 formatter,翻譯人員不僅能夠看到完整的訊息,而且在重寫句型方面有很大的彈性:

"Do you want to delete %s from %s?"
你是否要將 %s 從 %s 當中刪除?

看起來好多了。像 {#} 這種可指定順序的格式化字串甚至提供更大的自由度。

雖然我對日文一竅不通,但是我知道日文的語序和英文非常不同,再考慮日本人的性格,使用串接組成的訊息幾乎不可能翻譯成令日本人滿意的字串。是的,因為以前有些人沒有想到那麼多,所以我們最近收到來自日本方面的指正,而我這幾天的工作就是從程式碼中挖出不良的串接訊息、改寫成 formatter 形式。我想早期之所以會這樣寫,部份原因在於字串格式化函數是在開工一陣子之後才加入專案,即使在格式化工具加入專案後,也有人不清楚這回事。

所以這裡提出一個建議,如果你的軟體正處於開發初期,而且使用的語言或 framework 沒有很方便的字串格式化工具,強烈建議先去寫一個強健且可以吃 unicode 的格式化工具,說不定你的產品哪天會全球暢銷呢!

novus 發表在 痞客邦 PIXNET 留言(0) 人氣()