顯示具有 學習筆記 標籤的文章。 顯示所有文章
顯示具有 學習筆記 標籤的文章。 顯示所有文章

2016年11月1日 星期二

i18next 不進行跳脫處理

i18next 是一個 JavaScript 框架,可以進行多國語系的翻譯。最近工作上進行的專案就是使用它來完成。不過被人發現到一個 Bug ,輸出的文字,有些時候會冒出 HTML 的 <br/> 標籤。查找了一下,發現到是出在傳入作為翻譯參數的文字造成的。

作為翻譯的文字中,可以使用 {{變數名稱}} 來為翻譯的文字加上參數。如:

{
  "HELLO": "Hello, {{name}}!"
}

var output = i18next.t("HELLO", {name: 'Tim"});
// output = "Hello, Tim"

這種方式可以讓同一個翻譯設定變得更有彈性,不過相對的也可能帶來一些安全性的風險。因此 i18next 預設會將傳入的參數(上面的例子就是 name 參數)進行一些跳脫處理。像是將 < 變成 &lt; 來避免所謂的跨網域攻擊問題(XSS)。

而我的專案遇到的問題,就是在於我傳入的字串,中間包含了排版用的換行字元。
因此導致被 i18next 給處理掉了。

要避免這樣子的狀況,目前找到的作法,是在參數的名稱加一個減號,這樣 i18next 就不會對傳入的資料作處理了。

{
  "HELLO": "Hello, {{- name}}!"
}
// 一樣的呼叫方式, name 參數傳入的資料,就不會被處理。

當然這樣子的作法,有可能會引入一些安全性的問題。所以要注意使用。

2016年1月26日 星期二

對 ES6 的程式作單元測試

距離「號稱釋出確定的規格」的幾個月之後,既使是在技術前端的 NodeJS ,也依然沒有完全支援 ES6 的所有語法。就不用說那些依附在 NodeJS 之上開發出來的模組。看到大多數的實作方法,靠 Babel 來作轉譯回 ES5 語法,再進行後續的工作。

對於我這種等級的開發者, Babel 背後運作的原理、語法分析的實作方式都屬於玄之又玄的事物。大多數只要結果正確的狀況,根本不會想去看懂那轉回 ES5 語法的樣子。不過事情總有例外⋯ 就是作 Unit test 的時候。

在我使用的 jasmine 模組中,錯誤訊息會帶有例外產生在哪個檔案的哪一行,對於查找原因是很方便的。不過一但轉換成 ES5 語法之後,每個指令不會在和 ES6 原始檔相同的位置,造成許多困懮,需要有「好心人」作轉譯的工作。

後來找到了 「jasmine-es6」這個模組,只要把它裝在 global ,就可以直接使用原來的 「jasmine」指令進行如原先一般的單元測試,出錯的時候也會對應回 ES6 原始檔的行號,很方便。

npm i -g jasmine-es6

jasmine-es6 本身會改變 jasmine 模組的程式內容。所以若是移除重裝 jasmine 後,要記得再裝一次 jasmine-es6 將擴充的功能再設定回去。

PS.
後來發現一個叫作 「jasmine-babel」的模組,讓我後來再安裝的時候搞混。雖然在 npm 上可以查得到它,不過對應的 github 路徑已經不存在了。應該是一個不再維護的專案吧~

另外,如果使用 gulpfile.babel.js 以及搭配相關的模組來以 ES6 語法執行 gulp task。其中 gulp-jasmine 能夠在沒有 jasmine-es6 的狀態下執行。不過我還不會用它來顯示錯誤的行號,不確定有沒有支援顯示錯誤在原始檔行號的功能。

2015年8月19日 星期三

在 Asciidoc 輸出結果中加入區塊圖示

在 Asciidoctor 的工具輔助之下,一些預設就有區塊內容,像是「TIP」、「NOTE」⋯ 都能夠在輸出的時候被加上預設的圖示。只要在最開頭的設定值中加上⋯
:icons:font

就可以在輸出 HTML 的結果中,看到本來醜醜的介面被加上的圖示。

沒有深入研究是 asciidoc 本來就有的,還是 asciidoctor 加上的項目。總之,能夠讓輸出的結果更加賞心悅,是一件不錯的事情。

2015年8月13日 星期四

[Soma.js] 設定要注入的物件名稱

依賴注入似乎已經成為許多軟體框架的必要元素,它的概念仍然不易被人熟悉,但其方便性以及能夠帶給軟體開發的彈性是很大很大的。 Soma.js 是 javascript 的一個以 infuse.js 為基底開發的依賴注入程式框架(framework),依循它所提供的規則,可以自動偵測到建構式所需要的參數,使用 this 定義的物件變數,Soma.js 將在所有註冊在它身上的變數中,尋找相同名字的變數置入。

換言之⋯ 只要取相同的名字, Soma.js 能夠自動完成變數對應的工作。很方便,但也是其限制。要是一旦名字不同了呢?要是不同時期開發出來的程式,用了同一個名稱表示不同的名字呢? Soma.js 的對應機制是不是就無法順利運作了?

另一個會改變名字的地方在於程式的最小化,為了極致地減少程式碼所佔用的空間,會以較短的文字(像單一字母)取代變數名稱。如此處理的程式碼,很有可能會使得依賴注入失效。

同樣的情形也出現在同為 javascript 的 AngularJS 框架中,而 AngularJS 的處理方式,是在建立 controller, service 的地方,以陣列取代原先傳入建構函數的地方。陣列中列舉了每個注入引用的名稱,最後一個陣列元素才是建構式。由於程式最小化不會對字串進行處理,因此可以避免注入的對應出錯。

那麼回到 Soma.js 身上,它使用了 injector.createInstance 方法來建立物件,然而只接受一個參數,也只能是建構函數。它是支援在建構函數後頭增加其它的參數,依序作為建構函數的參數,不足的部分的由既有的注入對應機制處理、補齊。

不過,如果傳入的參數是要注入項目的名稱,會發現該名稱的字串,會直接作為參數傳入建構函數,而不是該名稱所對應的物件。因此,如果要傳入注入名稱的對應,不能使用 injector.createInstance 函數來達到。

最後的由其的基底 infuse.js 的文件中找到,它的作法是在建構函數上定義 inject 變數,其對應到建構時所注入物件名稱,經過實測的結果是能夠順利運作。至於物件內的變數要怎麼對應,這個部分就留待未來有需要再進行測試。

以下列個簡單的物件宣告⋯ (注意 inject 是定義給建構函數,而不是建構出來的物件上)
function MyClass(opt1, opt2) {
  // some code...
}
MyClass.inject = ['optName', 'otherOption'];
module.exports = MyClass;

2015年8月11日 星期二

在 asciidoc 文件中使用語法高亮

許久前照著範例輸入,卻怎麼也作不出上面講的語法高亮的效果。輸出的 HTML 還是「平平的純文字」,後來才發現,原來要在文件的開頭加上宣告,似乎這樣會多引入一些額外的 CSS  ,才能讓高亮的效果出現。

在主標題(文件最開頭,寫大標題的那區)加上⋯

:source-highlighter: pygments
這樣在輸入高亮語法時,就會被處理了。

除了 pygents 之外,還可以改成 coderay, highlightjs, prettify 。應該是其它幾種 CSS 主題吧~ 就沒有特別再去測試了,目前這種就讓我很滿意了。

語法的宣告很簡單,只要「[source,語法名稱]」就可以了。像是 javascript, php 這種比較單純,有一些則是要嘗試一下,像是我試了「shell, bashell, hash」三種,最後只有 bash 才被正確解析。

哪天有空再找找有沒有什麼表格,把所有支援的語法都列出好在未來作查詢。

另外,讓我有點意外的,也有支援 livescript 語法。算是一個驚喜吧~

[2015-10-5 補充]
重灌 mac 後發現,如果要使用 pygments 樣式的話,需要安裝 pygments.rb 這個套件。不確定在原來在打這篇文章之前就裝過,還是因為後來的 asciidoctor 安裝不會將它裝入。總之包含其它的樣式(coderay, hightlightjs, prettify)應該都要先安裝對應套件才能使用。

[2016-10-23 補充]
使用以下指令安裝 pygments.rb

gem install pygments.rb

2015年6月26日 星期五

Sinopia 試用

工作需要開發一些能夠重覆使用的 Javascript 模組,當然具有許多支援的 commonjs 與 nodejs 格式是首選,唯一的問題就是一方面希望能夠使用 npm 裡眾多的模組,但另一方>向自己所開發的一些內部使用的私有模組就不方便公開了。

花了一些時間尋找,看了 npm 那個要付費使用的私有模組庫,之後就遇到了這篇要提的 Sinopia。

Sinopia 並不是一個英文單字, Google 翻譯認為它是荷蘭文,是一種楬紅色顏料的名字。看不出和軟體本質的關連,就此打住不提。

它是一個依靠 Nodejs 建立網站的方式,建立一個能和 npm 套件溝通,提供自定模組的服務。當然,如果對它要求不存在於自身裡的模組,它會將要求轉向發到公開的 npm 主機。幫你把公開的套件抓回來。

除了抓下套件之外,也提供了在上面註冊帳號,讓自訂的模組也能使用 npm 既有的公開(publish)模組流程,將新的版本上傳。


試用了幾天之後,感覺還不錯,找個時間再試試看它能不能在 windows 上也順利運作。這樣平常工作的開發,應該會順利許多。

2015年6月5日 星期五

翻譯 LiveScript Style Guide

前陣子同事在說明專案要用到的 LiveScript ,提到網路上有個 LiveScript 的語法建議。個人還滿認同程式的寫作風格一致所能帶來的好處。因此就把網路的版本抓回來,由原來的 markdown 語法,改成另一個我正學習的 asciidoc 格式。

同樣把內容放在 github 上,也許第一次翻譯這種東西,多少會有所缺失。不過好歹也算是有個起頭,希望哪一天能夠幫到對它內容有興趣,但英文不好的程式同好。

翻譯的內容在這裡

2015年4月29日 星期三

fswatch 使用筆記

最近時常使用 asciidoc 的格式在建立文件,撰寫筆記。也練習使用 vim ,看看能不能如人家所說的「vim 成為最後一個學習的文字編輯器」。過程中遇到一個問題,雖然在 vim 中可以直接呼叫命令列指令來編譯出 Asciidoc 格式的文件。但是每次作點小修改,就得重複 :w 與 :!asciidoctor % 兩個指令,打久了很煩。
有沒有一個偵測到檔案儲存,就能自動替我執行 asciidoc 指令的方法呢?所以我找到了 fswatch 這個東東。

2015年4月13日 星期一

模組化設定值的開放與否

有一次和同事討論程式的作法,發現兩個人對於「模組化」程式的開發有滿大的不同。我認為應該多使用預設值,只公開必要、儘量少的設定值。而同事則認為應該讓參數有多種的變化性,這樣開發程式比較不會因為某些沒有被參數含蓋的變化功能,導致得回頭的查看、修改模組程式。

討論到最後,並沒有達到完全一致的共識,因為彼此提出的論點和舉的例子都無法說服對方。當然尊重別人的程式撰寫風格的前提下,都沒有強迫對方要照著自己的方式走的意思。最後我採用較為折衷的方式來開發,作為這次討論的結束。
回到家又再思考了一遍這個問題,回憶一下從前是如何作下「儘可能少開放」方針的原因。很清楚的知道並不只是單純的跟著「封裝原則」的建議。而是有其它理由支持這個論調。還好,最後終於讓我回想起來了⋯

2015年4月4日 星期六

貢獻在 GitHub 上的專案

這篇文章是用來記錄我從零開始學習 git,為了能夠貢獻一點程式到 gitHub 上。希望這篇記錄不單能作為學習的記錄,也能夠幫助到其它也想幫忙 gitHub 上專案,但是不知道如何下手的人。

先備知識

首先要先談談 git 的特性,和其它老牌的版本管理不同,早期在建立本地「沙箱(sendbox)」的時候採用 checkout 來得到某個特定版本資料,而 git 則採用 clone 的方式,將版本庫整個複製回本機上,因此除了要和遠端的版本庫同步的工作外,都可以在沒有網路的本機端完成所有操作。

要注意的是,本地和遠端的版本庫實際上是獨立的個體,依需求可以隨意連結或斷開關連。因此一個本地版本庫同時對兩個以上遠端保持關連是可行的。在推送(push)新版本的時候,只需要告訴 git 遠端主機是哪一個就好了。許多的 git 特性,都是由這個特性延申而來。

情境說明

先說說我的情形⋯

  • 在網路看到想要加入的專案,開放讓人貢獻程式碼
  • 但自己並沒有寫入這個專案的權限,既使有權限,也不知道應該如何作修改
  • 聽聞程式碼送交後,會有人進行審核,但找不到送審的地方,也不知道審核者在哪裡
  • 在討論區裡知道了有 fork 這東東,但版本庫 fork 回來,接著就不知道要作什麼了


關於我學習中間撞牆的詳細過程,不是這篇文章的細節。也許哪天有空再寫篇雜記吧!

2015年3月19日 星期四

用 Sublime 建置當下正在編輯的文件

為了避免那些常常出現,還看不懂的 Node.js 語法干擾我學習前端技術。打算狠下心來花時間對 Node.js 作點深入的了解。首先要先在同樣也在學習中的 sublime 進行設定,可以在編輯器中以快速鍵的呼叫 Node.js 執行正在編輯中的檔案,來加快學習的進度。Sublime 既然被稱作強大的文字編輯器,那一定有相對應的功能吧!

開始研究

sublime 可以由選單 Tools > Build System > ... 的列表找到內建的幾種建置模式。可以手動選擇,或是讓它停在 Automatic 的選項上,由 sublime 自行判斷。當選好或被判斷出適用於特定種類建置方式時。 Tools > Build 選單的狀態會是「可點選」,藉由點選它或是以快速鍵 「Command + Shift + B」或 F7 執行建置的動作。

不過 Node.js 不在預設支援的建置模式中,所以需要自行定義,由 Tools > Build System > New Build System... 選項,會開啟一個新設定檔,讓使用者可以自行定義。

2015年3月17日 星期二

學習 Unit Test 之三

在開發程式中使用單元測試,「封裝」這個概念似乎和單元測試相衝突。

封裝的原則是把程式邏輯隱藏,只保留必要的屬性、方法對外公開。這個基於保護的原則在單元測試中需要「觀察改變」的需要相互衝突。單元測試為了測出邏輯是否正確,就必須有對應的類別方法能夠觀察、確認數值的變化是否符合預期。將方法 public 變得無可避免。

在滿足單元測試需要的公開方法之後,希望達到「封裝」的目的,不要曝露出過多實作細節。就需要有個「過濾」的機制,這個時候「介面(interface)」就可以派上用場。其它程式只知道介面定義的方法,而不知道實作的類別額外公開的方法,原來為了單元測試的需要所開放的程式碼,就被介面所隱藏,以此達到保護邏輯的目的。

回過頭來看看之前所學,難怪看到的程式原則中,總是寫著「對介面撰碼」而不是「對父類別撰碼」。而程式碼中的註解文件(xDoc, 如 JavaDoc)中,也具有能將方法標注為「隱藏」的語法。看起來可能都是由於單元測試的發展而演化而來的吧!

2015年2月19日 星期四

學習 Unit Test 之二

萬事起頭難,Unit Test 也不例外。在練習使用的過程中,「要如何開始」這個問題困擾了我很久。手上有的是剛寫到一半的值物件類別,不能確定是不是應該替他們寫測試程式。只是單純的檢查「資料記到變數裡」,沒啥意義。經過一些測試,慢慢抓到一些模糊的感覺,在這裡作點記錄。

回到程式的本質,就是處理資料。所以撰寫測試程式就應該是確保「資料被正確地處理」。所以測試程式的輸入和輸出,應該是不一樣的。既使只是數字變成字串,或是物件變成 XML 格式字串都算是改變的一種。當然輸入、輸出的改變可能是數值計算、整理作為 API 回傳值或著是分析、篩選出滿足條件的內容之類,總之,就是「有處理,就有測試」這樣子原則。

所以,一開始建立值物件的時候,不需要寫測試程式。在撰寫由檔案/資料庫讀出、建立值物件時,就要測試來源資料和值物件的內容。當確保了值物件的初始建立後,就可以拿這些建立好的值物件來進行其它運算,分析的工作。這樣,不用在測試程式中一行一行的打程式建物件,把更多的時間用在思考如何驗證結果,撰寫邏輯規則。

沒有資料,就很難進行的模擬的測試。反覆使用程式碼一個個地建立物件,足以消磨一個人的心。而且一旦物件格式改變,那麼需要異動的程式碼可能也會隨著專案發展變多。所以由統一建置的「工廠」來提供資料有是需要的,能夠快速複製新的版本,再修改來滿足其它測試需要。

所以,我覺得測試驅動的程式發展,應該是由值物件,以及建立讀取外部資料來產生值物件的類別開始。接著才會有許多不同變化的資料組合來模擬不同情境。

2015年1月28日 星期三

專案開發自勉

作為一個程式人員,總想著能利用程式來作些自己覺得有趣的事情。作個能 Open Source 的專案,在心中已經萌芽一段時間,卻一直未能正真進入開發階段。到咖啡館看書的時候,剛好聽到鄰座的教授和學生討論專題,心有所感。綜合之前看過的一些文章,將當下心得記錄下來。
相信工具 讓事情開始進行

相信工具 讓事情開始進行

隨著接觸過的專案越多,考慮的點也跟著的變多。開始的時候滿足於自己能夠「顧全大局」的成就感,但是也漸漸發現自己撰寫程式的速度不如以往。雖然寫出來的程式品質有跟著提高,但也隨著專案進行,發現許多當時考量的東西,最後不是沒有用到,就是需求改變而不敷使用,時間在無形中被浪費掉。倒不如早早開始動工,相信以依照現在的方法和工具,都有機會能夠將偏離的方向導回,沒考量到的部分予以補齊。

當然光是「相信工具」是遠遠不夠的,還要去學,去實踐那些工具和原則。像是不斷確認開發是朝著目標走,以此定義單元測試,並在發展的過程中反覆進行程式碼的重構。否則,只是單純的盲目前進,以及天真的期望哪天醒來,所有的問題會自然消失。

真正了解工具的背後意義,相信它們能夠幫助修正問題,然後就開始實作吧!不斷讓這些工具加入,讓事情發生!

解決問題 遠比用新技術更重要

無論一台機器功能再多,性能再好,如果不能用來打電話就算不上是一台手機。當為了追求的新的技術、新的管理方法、新的設計流程,一旦遺忘了根本的初衷,那麼產出的只一個堆積許多功能的四不像。一個連自己都不知道有什麼價值的東西,當然難以得到其它人的認同。所以產品的定位,想要解決的問題以及讓使用的人得到什麼價值,遠比用哪一種技術重要得多。

不管是 Scurm 專案發展、UML 圖或是 Big Data 、RWD ⋯⋯等等技術,都是為了解決在產品開發上,會遇到的一些問題。但也大多止於「產品開發」上,而不是「滿足客戶需求」或是「創造價值」。雖然學習各種新技術,能夠減少一些時間的無謂浪費,增加一些新的可能。但絕對不應該將所有的焦點都放在「新技術」這個議題上。選擇、引用,甚至是學習新技術,顯然比研究客戶問題、提出解決方案要簡單、不費腦力。看過一些人沉浸在新技術的堆疊,近乎在逃避解決客戶問題的責任。必須引及為戒,不能陷到這種狀況中。

片段時間 就開始 重要的是方向定下來

「我有想法,但沒有時間,找不到適合開始的時間點。」這個問題困擾了我許久,總是在一個念頭的開始,伴隨著公司加班,或是親友或自己的事情干擾,導致最終念頭仍然只是一個念頭,還是沒有被實現。因為如此,我的在職碩士,花了我整整五年的時間才完成,回頭來看還滿有趣的。前兩年我順利的完成所有的該上的課,沒有一科被當或出現危機。然而一個碩士論文卻花了我三年,而實際用在製作我的畢業論文的時間,大概才半年,那忙亂的半年中產出了一篇足以讓我畢業的碩士論文。而那半年之中,還有公司的專案趕工、上線等壓力在,常常強迫自己早點睡,六點起來寫一點文字,最後組成整篇論文。

事實上,我在完成論文的那個時段並沒有比較輕閒,所有的文字都是在片斷時間中撰寫,最後一兩週才抽出比較完整一些的時間去順槁。因此由小看大,表示別等著完整的時間才開始想作的事,既使只是片斷的工作成果,也能夠積少成多讓自己離目標更近一些。有一個明確,短時間不會被改變、大幅調整的目標,就可以開始動工了。大原則不變,其它的東西一面作一面微調方向就可以了。讓事情發生!比大量的規劃卻零產出有意義得多。

需求優先 別卡在細節

一個功能能夠有多少種變化?使用者操作上會不會看不懂?需不需要防呆機制?網站的安全性夠不夠?效能能不能讓主機承受上萬人同時操作?雖然這些問題對於一個成熟產品來說是必要的,需要常常去檢視,研究尋找更有好的解決方案。不過對於一個剛開始的計劃而言,這些都太遠了,不值得讓它們佔用本來就不太夠用的腦袋空間。人們可以忍受要等上一兩秒才算出報表的統計程式,但不能接受一個全世界最快,但只能算加法減法的計算機。

專案的目的是什麼?最核心想達成的功能為何?什麼是達到功能的最小可檢視流程?這些才是最需要常常問自己的問題。不斷的探索使用者遇到的問題,嘗試想出各種滿足需求的可能,去驗證它,分享它,再回頭去看看和大方向是不是一致。等到組合成一個夠完整的解決方案,再回頭去思考其它和需求比較沒有關連的問題或是優化產品的效能。

如果擔心一開始的程式規劃無法面對未來的變化,那就要在每一次的開發流程中,導入重構的技術。去相信重構的技術能幫助我們重新設計程式規劃,然後,開始進行吧!

第一個版本在哪裡?prototype?

產品終究是要給自己以外的人使用,所以,可展示的版本,或稱之為產品的原型,是發展的里程碑。最終目標太遠,往往會讓人失去想要達成的動力。最好能夠早一點作出能夠給別人看的原型產品,一來目標較近,有機會能在燒完全部熱情前完成,二來可以聽聽其它人對於這個東西的看法,能夠早一點作出修改,或是增強部分功能的力度。總之,都要比自己閉門造車完成後,才發現不合交通法規上不了路的好。

也許現在的想法有一些未盡理想之處,不過就像前面所說的,總是要先起了個頭,才能知道要如何改進,才知道對的方向在哪裡。

2015年1月24日 星期六

MVC 框架 - 容器與內容物的分離

我會的程式語言種類並不是很多,對於 MVC 框架的了解也是最近研究測試與重構後,才有了更深的了解,發現有一些自己與別人對於它的誤解,在這裡作作記錄和分享⋯

Context 物件

記得是在學習 Andoird 程式的時候,第一次接解觸到「Context」這的單字,在一些書本不是翻作「上下文」或是省略不提。花了許多時間嘗試理解,最後終於在字典外的一個討論串手有了一些些的了解。如果要我翻譯它的話,我會翻作「關連」。

在 MVC 框架中,會有一個作為組合所有元素的「容器」,在命名時常會使用「Context」這個單字,它的作用就是讓本來沒有交集的元素,相互之間能夠互動,讓值物件能夠被注入到的需要的物件中,讓發出的事件能夠被偵聽的物件收到。維繫這些元素之間互動關係,就是「Context」的責任,所以我認為翻成「關連」會比較好。

在 MVC 的概念中,每個元素都是獨立的,不知道會知道其它元素存在。因此可以更彈性地抽換、組合來滿足需求。而在這些元素之外,需要有個「容器」來裝它們,由於容器的程式實作通常已經被框架的開發者作完了,通常只需要繼承並覆寫需要改變方法,或是 new 出物件後,指定需要包含的類別有哪些,它們之間的關連就會被建立好。

在 Java 裡的 spring 框架,甚至只需要在設定檔指定套件的範圍,就能夠直接作「掃描檔案,判斷類別是否為 spring 元件」的工作,增加新元素變得更容易,也不容易漏了什麼關連。雖然這並不是 spring 框架的特有的能力,不過是我在其它程式語言的 MVC 框架中沒看到的特色。

2015年1月19日 星期一

[Robotlegs] Actor 找不到 IEventDispatcher 的依賴注入

今天嘗試將 FlexUnit (1.5)和 Robotlegs 兩個 framework 結合在一起,作為重構程式碼之用。開始還算順利,當我把假類別置換成整理過的實際類別時,測試回報「找不到 IEventDispatch 的 Inject 資訊(如下)」,造成無法開始撰寫第一個測試案例。

Error: Injector is missing a rule to handle injection into property "eventDispatcher" of object "[object TestingLogic]". Target dependency: "flash.events::IEventDispatcher", named ""

在程式碼中查了半天,就是沒有看到有任何需要 Inject 這個類型的資料。因為  Actor 是 Robotlegs 的既有類別,理論上應該不會出現缺少需要的 Inject 物件才是。所以中間一度懷疑是不是之前的同事去手動調整了的 Robotlegs 的核心程式。花了一點功夫,把 swc 解壓縮來看看,也看不出來有什麼異常⋯ (中間還查到另一段無關這次錯誤的歷史程式)

最後把焦點拉回到 Robotlegs 本身,因為 Context 本身具有發事件的能力,因此作為其 Model 元素的 Actor ,應該也是利用和 Context 一樣的物件來發事件,否則 Context 就得偵聽一大堆 EventDispatcher 所發出的事件。所以缺少 IEventDispatcher ,應該和 Context 有關,其中最可能的,就是在初始化的時候所帶入的 DisplayObjectContainer,這個類別有實作 IEventDispatcher 介面。

最後在這個地方的參數加上 new MovieClip(),就解決了這次的問題。也發現到原來在 Robotlegs 的事件發送,是依靠建構時傳入的元件,而不是由自己實作 IEventDispatcher 介面。不知道這個機制在 2.x  的版本有的改變,有機會再去試試看。

作個筆記⋯

2015年1月17日 星期六

學習 Unit Test 之一

為了重構一個專案既有程式碼,開始了重構的學習歷程,這些文章會把一些學習與實作中的心得記錄下來。剛開始深入研究的自己,也估不出來會用上多少篇文章來記錄,就估且用數字來的編號,等到未來遇到更好的文章命名方式,再回頭調整吧!

開始的篇章想先記錄的,是花了一兩個星期看完 Apache FlexUnit 指引之後的感想。作為一個成名已有兩三年以上的技術,在學習上並沒有我想像中的那麼容易,一些套件的名稱有了改變,原有的範例程式不能執行,或是舊版的函數庫已經找不到,得所有函數庫都升級到最新的版本。作為一個已經一段時間新東西可討論的技術,往往看到的都是數年之前的文件,當遇到問題,無人可問的無助感在心頭揮之不去。

所謂的「單元測試」,就如同其名一般只針對「單元」進行測試,所以雖然它也能夠發展成為某些「功能測試」的工具,但並不是它的設計初衷。從前的我一直認為「單元」只是表示它的測試「能夠細到每一個小單元」,並且對於每一項測試並不保證順序,以及每一次的測試都需要重頭執行測試項目初始化感到不解,認為它會造成在測試上的一些不確定性。

2014年3月5日 星期三

使用 GraphicsMagick 將圖片轉正

早期數位相機儲存的照片不帶有方向資訊,所以需要再手動把相機撗擺所拍出來照片轉正。而如真新一點的照像機,包含智慧型手機會在檔案裡加入像是焦距、光圈…等資訊,而方向也是其中之一。在這裡可以看到其中的定義,在 Windows 8 或是在 Mac 中看到的圖片縮圖、預覽會先抓取這個資訊預先轉正,所以平常沒有這種感覺。

不過瀏覽器是一個例外,由同事測試得到的資訊,在 iPad 上的 Safari 會自動偵測圖片方向,並作轉正的動作。而其它 PC / Mac / Android 的瀏覽器都還是用圖片原來內容呈現。

這造成一個問題,當使用者利用手持裝置拍照並直接上傳,在瀏覽器所看到的圖片方向是不能被預期的。因此才會有使用 GraphicsMagick 來替所有上傳圖片作轉正的需求。

2014年2月14日 星期五

Zinc 全螢幕功能需要注意的地方

Flash 可以輸出成為執行檔,不依靠 flash player 直接在作業系統中執行。另一種角度來說,就像是把自己寫的程式和 flash player 包在一起。成為執行檔可以打開一些限制,像是能夠同時讀取本機與網路上的資料,或是執行系統命令。不過本來就沒有的寫入檔案功能,並不會因此冒出來。

全螢幕的功能,就是變成執行檔可以使用的功能之一。

在 MDM Zinc 裡,猜想是因為帶入的多視窗的概念,導致既有的方法失效,需要用它所提供 Forms 的方法來達到視窗的最大化、最小化、還原。最大化和全螢幕不同,全螢幕的狀態會把系統工具列、 Dock 等也一併隱藏。

使用 Zinc 開發的專案,很早就發現一個狀況,就是全螢幕的功能正常,但是取消全螢幕的功能卻時好時壞,系統工具列在取消的同時出現,但是程式並沒有回到原來視窗的狀態,還是維持全螢幕的大小,只是上頭多出現了系統工具列。一直到最近才找到時間去研究這個問題。

2014年2月9日 星期日

使用 Joda-Time 取得各時區的時間

話說前陣子研究 Joda-time 來取得各個時區的時間後,就把它應用在專案裡面。不過幾天專案發現出問題,讓我發現它的一個小小的問題。

問題的原因發生在把資料庫的時間轉換成我希望的時區,所以我寫了下面這個函數…
public Date getLocaleTime(Date date, String TimeZoneID) {
  DateTime time;
  if (date == null)
    time = new DateTime(DateTimeZone.forID(TimeZoneID));
  else 
    time = new DateTime(date, DateTimeZone.forID(TimeZoneID));
  return time.toLocalDateTime().toDate();
}

乍看之下沒有什麼問題,不過當選擇到某些特定的時區的時候就會出狀況,說 Joda-Time 不支援這個 TimeZone ID。