2012年11月25日 星期日

[開箱] 今年的生日禮物 Tissot PRC 200 機械錶

去年的生日禮物是耳機 (AKG K-701) , 今年則是因為原本戴的FOSSIL錶打球的時候壞了,修又差不多買新的一半以上的錢(壞的好嚴重呀), 備用的錶的錶帶又常常脫落戴的不舒服, 所以就打算換隻錶

本來是看SEIKO, CITIZEN, 看金城武跟王力宏代言看起來蠻帥的, 日本錶功能又多, 科技感濃厚, 就有點感興趣, 不過直到昨天, 跑去看007電影Skyfall, Bonds戴的Omega也蠻帥的呀, 不過自己平常對錶沒啥研究, 不知道, 這還真是我買不起的高貴, 買不起Omega還是繼續跑去專櫃看了SEIKO, CITIZEN, 實際上看了實物, 還是失望了, 這不是我想要的型, 才發現我喜歡的並不是這麼濃的科技感, 而是比較古老一點的機械

再逛了一下瑞士的錶款, 還真一個比一個高貴, 好像只有TISSOT是外型跟價位還是我可以接受的, 所以今天就找了老婆, 小遠跟我去敗了這隻 - TISSOT PRC 200機械錶, 這還真是我戴過最貴的(羞), 也是第一隻機械錶

紅黑色的外盒:

躺在盒內的樣子...其實這是偽開箱啦...為了拍照再擺回去的 XD

錶面很單純, 沒多餘的圈圈(?!), 我還蠻喜歡那秒針的, 上面有個T, 其實我更喜歡BALL的指針設計, 不過那在預算外了, 白色錶面銀色框是我喜歡的, 黑錶面跟玫瑰金就不是我的菜了... ^^

透明的背面看的到一些機械錶的結構

戴在手上的樣子

此外還有送一條贈品, USB 線, 不過這種線我有好多條了.... XD 

2012年11月13日 星期二

[Go筆記] UUID package

自己想做的東西可能需要一個UUID的產生器, 找了一下既有的packages跟網路上的, 好像沒一個自己滿意的, 所以就自己從java.util.UUID po過來

Source在此: https://github.com/julianshen/GoUUID

目前只implement RFC 4122 Version 4

Sample:

2012年11月7日 星期三

[node.js] 在heroku上用bower管理前端第三方元件

在做web applications時,或多或少都會使用到像是jQuery, bootstrap這類的第三方元件,使用已經host在既有CDN 的版本(比如說google的)是一個不錯的方法,但不是每一種都有這類方案,一個個從各網站下載回本地端又不是那麼容易管理,bower就是為此出現的,bower是一個類似npm的軟體,由Twitter所開發出來且是開放原始碼,所不同的是,npm是管理node.js相關的套件,但bower是管前端的

舉一個例子,你可以利用bower來安裝jQuery :
bower install jQuery
bower會把jQuery 安裝到"components/jQuery" 目錄裡

在npm , 你可以把所有相關的模組設定在package.json中,這樣就不用一個個下"npm install mypackage"這樣的指令了,bower也有類似的設計,只是為了避免跟package.json造成混淆它採用的檔名是component.json,內容跟package.json差不多:
{
    dependencies: {
      "JQuery": "*"
    }
}
在Heroku deploy node.js app有個很方便的地方是,當你做git push 後,它會根據package.json自動幫你安裝相關的node.js 模組,但不幸的是它並不支援bower,只支援npm

還好Heroku很有彈性,可以藉由buildpack來自己加這部份

buildpack API其實還蠻簡單的, 基本上只要準備三支shell script:
  • bin/detect
  • bin/compile
  • bin/release
大部分的東西, 大多在"bin/compile"裡完成的

自己做的buildpack也只要放github, 然後將自己app的buildpack指定到這來即可 (使用heroku toolbelt):
  • 新建的程式使用自己的buildpack: 
    heroku create myapp --buildpack https://github.com/heroku/heroku-buildpack-ruby
  • 既有的程式更換buildpack:
    heroku config:add BUILDPACK_URL=https://github.com/heroku/heroku-buildpack-ruby
當然, 不需要重頭建立自己的buildpack, Heroku官方的buildpack都有open source在github上, 如Node.js buildpack, 所以只要fork出來修改即可, 因此我從Node.js buildpack fork出一個新的buidlpack, 主要的修改是:

  1. 安裝bower
  2. 找出所有的component.json並用"bower install"安裝套件
本想說 "1" 應該蠻簡單的, 因為bower也是用node.js開發的, 應該只要用npm install bower就搞定了, 但事實是, 這樣會碰壁, 因為bower採用了lodash , lodash跟Heroku的npm似乎八字不合, 安裝過程到lodash的post-install就會失敗, 也沒明顯的錯誤, 只說這應該是套件問題, 而去查了lodash, 也有人報過類似的issue, 但作者卻以lodash沒問題應該是npm的問題把這issue給關了(鬼打牆?), 但:
  • 自己電腦上安裝bower或lodash都沒問題
  • 在自己的package.json加上lodash, deploy到Heroku也一樣掛
  • 在package.json裡設定engine裡的npm版本到最新的1.1.65(跟自己電腦上一樣版本), 也一樣不行

那...就不得不懷疑是npm問題了, 查了原本buildpack寫的, Heroku的node.js和npm其實是拿他們自己放在S3的binary package來安裝的, 可疑!

因此就使用了下一招 - 用npm來裝npm

用Heroku系統內的npm來裝npm是可行的, npm install npm的結果是, 會有一份最新的npm被安裝到node_modules底下, 可以用"node_modules/.bin/npm"來呼叫這版本, 因此就加上了:
node_modules/.bin/npm install bower
Bingo! 這樣可行, bower一樣被安裝到 node_modules/.bin底下, 加上 "2"的邏輯到"bin/compile"後就大功告成了,

有修改的部份只有"bin/compile", 比對一下commit history就可以知道我修改過啥, 中間有做了很多實驗, 所以有不少垃圾commits, 可以忽略

如果有需要這版本buildpack, 也歡迎利用:

https://github.com/julianshen/heroku-buildpack-nodejs




2012年11月5日 星期一

[node.js] 用npm安裝放在github上的module

剛剛為了想要做一個東西, 需要用到Flickr API, 本想要拿Passport.js來處理Flickr OAuth的部份,但卻發現, FLickr Strategy的部份不但年久, 而且permission這部份居然是hard code "read", 由於我想做的東西是要write, 其實是可以靠overwrite "userAuthorizationURL"來達到這目的, 不過這樣不好看, 所以就乾脆自己fork一版來改 (Github真是好物來改)

改完後的一個問題是, 原本可以用"npm install passport-flickr"來安裝這module, 但由於我fork出來的並未註冊在npm, 所以就得用另一個方式:
npm install git://github.com/julianshen/passport-flickr.git#master
這方式是直接把git url給npm, 不過要deploy上heroku就麻煩了, 還好寫在package.json裡也是沒問題的
"dependencies": {    "passport-flickr": "git://github.com/julianshen/passport-flickr.git#master"}
這還蠻簡單的, 只是把原先寫version的地方換成git URL就好, 在Heroku上也是沒問題的

題外話: 剛deply到heroku上時發現express 3.0.1無法安裝, 原因是我忘了在package.json裡註名我node.js的版本, 這種狀況下, Heroku會自動幫你挑v0.4.7版

2012年11月3日 星期六

竹北。梨頭山

今天有點時間, 想說出門拍個照, 在網路上稍微查了一下看看有沒啥制高點可以拍高鐵,平常從底下拍高鐵拍的有點無聊了, 所以就找到了梨頭山, 反正也離家不遠 到梨頭山, 可以從文山國小有個登山步道上去

 
View Larger Map

住這邊這麼久了, 說真的, 還沒來過這, 碰了運氣找到了入口, 感覺好像還真是個人煙罕至的地方

DSC04718

太久沒啥運動, 這坡度爬起來還真有點喘, 也不知道該爬多高才可以看到高鐵, 其間曾一度在樹林縫隙看到了軌道, 不過這並不是最佳位置, 到了山頂上, 果然名不虛傳呀, 高鐵站周邊景色一覽無遺

DSC04957

在這邊用長焦段的鏡頭並不難捕捉到高鐵的身影, 不過新買的反射鏡實在令人失望, 不但不好對焦畫質也差, 只好用super takumar 135mm這隻俗又好用的鏡頭


DSC04917
DSC04889

這邊的景致還不錯, 而且離我家非常的近, 可以俯瞰高鐵站

下次有機會再來去湖口另一個拍攝地點看看好了....

2012年11月2日 星期五

[Go 筆記] Type, method, and interface

"Go was born out of frustration with existing languages and environments for systems programming."
Go 是為了作為一個系統語言(systems programming language)而存在的, 它跟天下知名的C語言有同一個父親 - Ken Thompson , 作為一個系統語言, 它並不是直譯式語言, 也非跑在虛擬機(virtual machine)上, 而是貨真價實的像C一樣是先編譯(compile), 而且也是屬於strong and static type的語言, 這表示, 變數型別是預先宣告/決定的, 而且是不能半路變更的, 變數可以像這樣宣告:
var StrVariable string 
var IntVariable int
這邊跟C, Java之類的語言不同的地方是, 型別定義是在後面不是放前面, 剛看到時我以為我會不習慣, 但卻花沒很多時間就適應了, 可能是我在很早以前寫過PASCAL的關係吧, PASCAL也是類似的寫法

但, Go其實還引入了一些dynamic language的特性, 因此在Go內也可以看到未經上面類型的宣告, 就直接指定的敘述, 像是:
strVariable2 := "Hello Go"
這敘述並不代表Go也有dynamic typed的設計, 其實這設計是同時結合了宣告跟指定(assignment), strVariable2並不是沒有型別或動態型別, 因為":="的關係, 使得strVariable2一開始就被宣告成後面值的型別, 因此上面那行跟下面一樣:
var strVariable2 string
strVariable2 = "Hello Go"
同理, "intVariable2 := 1"這敘述表示intVariable一開始就被宣告成整數(因為1是整數), 所以它還是一個strong typed的設計, 這邊比較要注意到的一個陷阱是"="和":=", 在已宣告過型別的變數, 是用正常的"="來指定值, 但在未宣告的變數, 必須要用 ":="

你不能做的是... "strVariable2 = 1", 因為strVariable2在前面已經":="被宣告成字串(string)

在Go, 你一樣可以自定型別, 結構(struct)
type MyString string
type User struct {
    Uid int
    Name string
之後, 你就可以用MyString或是User來宣告變數, 像是
var M1 MyString
var User1 User
User2 := User {1, "julian"}
"type MyString string"有點像是C語言的typedef, 可以讓你以另一個型別(MyString)來替代原本的型別(string), 但它其實還有個妙用, 在後面會再提到

Go是一個functional programming language, 所以它並沒有物件導向觀念

沒有"類別"(class), 沒有物件/實體(object/instance), 但, 它卻有"方法"(method)和"介面"(interface), 聽起來有點四不像, 但其實這部份還蠻有趣的

先說到"方法"(method), 在Go, 你可以為你的型別設計一個"方法", 像是這樣:
func (u *User) Hi() {
    fmt.Printf("Hi! I'm %s. The %d user.\n", u.Uid, u.Name)
}
這邊"Hi()"就是屬於"User"的一個方法, 呼叫"User2.Hi()"即可執行它, 方法跟一般的函數一樣, 所不同的是, 前面多了一個"(u *User)" 以這例子來說, 這邊就是定義了"Hi()"的母體是 *User (*是指標- pointer的意思, 就不在這邊解釋)

這邊有趣的地方是, 你可以為任何自定型別創造"方法", 包含函數(function), 這在"net/http"內就可以找到類似的應用:



在這例子中, HandlerFunc有一個ServeHTTP的方法, 但HandlerFunc本身其實是一個function

"介面"(interface)也是一個蠻妙的東西, 在Java裡, interface必須要宣告"實作", 亦即"class MyImpl implements MyInterface", 也就是你必須指定某個class實作了某個interface

但在Go, 則是很不一樣, 在Go裡, 你可以宣告一個"介面"(interface) 像是
type MyInterface interface {
    Foo()
}
但你不需要宣告某個型別"實作"了這個interface, 在Go, interface反而比較有"暗示"(imply)的意味, 也就是, 下面的例子, 不用任何宣告, 你可以把MyString自動當成它也可以是一個MyInterface:
func (s MyString) Foo() {}
因為在MyInterface的定義中, 它含有一個"Foo()", 當你替MyString宣告了一個"Foo()"的方法時, 就自動讓MyString變成了一個實作了MyInterface的型別

下面用一個比較完整的例子來總結:


在這例子中, "CallFoo(MyInterface)"接受一個MyInterface的參數, 並執行它"Foo()"的方法, 由於"Aa"(字串)和"MyHandler"(函數)都是有一個"Foo()"的方法, 所以他們都可以被當做MyInterface作為參數, 同理, 回到前一個HandlerFunc範例, HandlerFunc其實也可以被當做Handler這個interface來使用, 在"net/http"的API中就是用到了這樣一個技巧