reality

on web, mobile and software

[REPOST] 登記成為「資訊科技界」功能組別選民

| Comments

作為 IT 界一員,你是否常感到 IT 界功能組別的代表未能 反映 你的 觀點呢?為了不讓悲劇重演,你可以登記做選民,為自己和業界投重要的一票。

據「立法會條例 20Z 資訊科技界功能界別的組成」,選民必需是指定學會和團體的會員。 根據我的調查其中 BCSIEEE 手續較簡便。以下是我的筆記:

注冊成為 IEEE 會員以及登記做選民

  1. 開啟 IEEE 網站,選擇 “Join IEEE”

  2. 請先到 qualitications 確認自己已有 Professional Membership 的資格,然後選擇 Professional Membership,按 ” Begin join Process”。

  3. 網頁會自動跳到 IEEE Shop 網站。用網站的戶口登入,或開啟一個新戶口。注意地址需要是在「香港」地區才能加入香港分會。

  4. 登入後會自動加入 “IEEE Membership” 。要再新增一個合資格投票的 Society:IEEE Circuits & Systems Society, IEEE Communications Society 或 IEEE Computer Society 其中一個便行。

  5. IEEE 會員以年為單位,每年12月31日到期。在下半年申請,可免一半年費。例如加入 IEEE Membership 和 IEEE Communications Society ,現在 (14/6) 的費用是 USD $83.00。 付費後即可成為 IEEE 會員。

  6. 確認電郵中有連結住 myieee,那裡可以看到自己的編號和其他資料。
  7. 填寫及寄回 個人登記為功能界別選民及選舉委員會界別分組投票人申請書 REO-41

請緊記登記必須在2012年5月16日前完成,由於處理需時,請不要遲疑了!快點登記做選民吧!!

注意:以上內容雖然力求準確,但只供參考之用,請各位小心確認資料,一切後果本人概不負責。

UPDATE:

哇靠,原來當年劉夢熊選過IT界選委

參考資料

相關文章

Using 3rd Party Ruby Library in RubyMotion

| Comments

These few days I have been playing with RubyMotion.

They have documents on using Objective-C libraries. So using familiar library such as TouchJSON is not an issue.

How about using Ruby library such as BubbleWrap? There are no documents on how to include and write gems in your project yet. Before it is ready, you can do this:

Add the library as git submodule:

1
git submodule add https://github.com/mattetti/BubbleWrap.git vendor/BubbleWrap

Add the path to the library sources to your project ‘Rakefile’

1
2
3
4
Motion::Project::App.setup do |app|
  app.name = 'myapp'
  app.files += Dir.glob(File.join(app.project_dir, 'vendor/BubbleWrap/lib/**/*.rb'))
end

Thats it!

有關 Bundler 的二三事

| Comments

今天聽 Ruby Rouges podcast #045, 學了一些之前不懂的 bundler 小知識.

Dependency management 問題是 NP-Complete

Bundler,或任何 dependency management 軟件的算法,也是 NP-Complete 的問題

Bundler 的工作其實是在所有 dependencies 的版本上搜尋能符合 Gemfile 內容的解。大部份情況 bundler 也可以很快找到答案,但有一些 Gemfile 會讓 bundler 停轉。雖然看上去像 bug,但實際上不是個 bundler 作者可以輕易解決的問題。

話雖如此,但其實有方法加快 bundler 的搜尋:在 Gemfile 的 dependencies 盡量指定你想要的版本。

例如這個 Gemfile 的 Gems 沒有指定版本:

gem 'rake'
gem 'rack'
gem 'jekyll'

Bundler 預設值下,gems 版本等於 ‘>= 0’ (每一個版本也可以)。假設每個 gems 有 10 個版本,(簡單起見不計他們的 dependencies)這個 Gemfile 的版本的 search space 便有 103 個。

但如果將之指定版本 :

 gem 'rake', '~> 1.3.0'
 gem 'rack', '>= 0.9.2'
 gem 'jekyll', '>= 0.11.2'

那他們的 search space 便會降到只有附合條件(數個到數十個)的版本了!

一般會讓 bundler 停轉的 Gemfile 在指定較少範圍的 gems version 後都能解決問題 。

semantic versioning 和 approximate operator

如果你在用 Bundler 那你大概己聽過 semantic versioning。上面 Gemfile 例子裡的 approximate operator (~>) 意思為 “只要版本大過或等於指定的版本,最後一個版本號碼可以不理”。例如 ‘~> 3.1.2’ 即 ‘>= 3.1.2 and < 3.2.0’,’~> 3.1’ 等於 ‘>= 3.1 and < 4.0’。這是基於 semantic versioning 的假設:如果在版本 a.b.c 測試過,,那麼在之後的 a.b.d 也應該可以運作正常 – 因為最後一個數字僅代表 patch / bug fix 版本。

值得留意的是,~> 這符號之前沒有名字。Rubygems 的 committer 有段時期將之稱為 “spermy operator”!這事還引發了一串討論,最後 ~> 官方名稱就確定爲 “approximate”。

Bundler 1.1.0 的改進

如果你有用過 bundler 也會覺得它初次 bundle install 時很慢。也許大家會覺得那是因為 dependency resolution 的問題。然而大多數時間這也不是 NP-Complete 問題的問題. bundler 一直慢的原因是因為在解決版本問題之前它先會由 rubygems 下載整個 rubygems 資料庫 – 由古到今所有的 gems 的不同版本 – 將之解壓和放到計憶體上,這不是個很快的過程。

在 Bundler 1.1.0,他們使用了 rubygems.org 的新功能:只返回需要 gems 的資料。這讓需要下載和處理的資料由 M 降到 K 為單位!如果你在用 Bundler,那你一定要看看你更新到最新版本了沒!

推介你聽聽 Ruby Rouges podcast #045 裡面有我未能盡錄的好內容啊!

Re: 邀記者實測:數碼通狂踩CSL LTE稱3G做得好才重要

| Comments

今天在傳媒看到這篇文章:邀記者實測:數碼通狂踩CSL LTE稱3G做得好才重要

看數碼通的說法還真是玄之又玄,但其實可以解讀為:

貶敵抬己,其法有三。

其一,敵先有 4G 者,先貶其覆蓋不足。

其二,敵覆蓋充足者,貶測試者擇地失當,氣候不佳。

其三,若敵方長勝,貶”若果一多人用,頻譜多不等於速度會快”!

… 這麼一來自家用戶就士氣一振了吧?

用 Framework 的方式重用 Cocoa 源碼

| Comments

開發軟件時「重用」是十分重要的概念,然而到此為止在 iOS 下要重用自己的源碼或開放源碼的專案卻不是那麼簡單。

通常我們有以下方法重用源碼:

  1. 把獨立的源碼檔外分開存放,新專案需要他們時,手動把源碼拉進 XCode。大部份 opensource Objective-C 專案也是用這方法。例如 ASIHTTPRequest
  2. 做一個 Static Library 的專案 ,再在新專案裡把這個 static library 設為 dependencies。在 build 時就會自動 build 這些 dependencies 專案。一些比較複雜的 library 例如 Three20 就是用這種方法。
  3. 跟 Apple 的做法一樣,把專案做成 framework。這方法 framework 以 binary 的型式加進專案中,編寫新專案的人不需理會和編譯 framework。

第 1 個方法是最簡單的方法。然而它要求 Library 用家對 Library 源碼有一定認識:需要用那些檔案,要怎樣編譯等等。如果 Library 有新的源碼,用家又要把新的檔案加進目的專案裡。

第 2 個方法是為了解決管理專案的問題而作的。它的好處是用戶不需要懂得怎樣管理 Library 專案。但用戶仍需要注意編譯 Library 專案的問題,如果 Library、編譯器或 IDE 更新了,有可能不能重新編繹一模一樣的 Library。

第 3 個方法讓用戶最輕鬆,基本上只需要把 framework 加進目的專案中便行。你甚至可以控制那些 headers 開放給用家,封裝 API 時更有彈性。

唯一問題是:Apple 沒有公開怎樣造這種 framework 的秘密!對,XCode 沒有 framework 的 template,它的內部運作也沒有甚麼文件說明。幸好有厲害的開發者研究出怎樣做 framework 的方法,並將之寫成 XCode template。只要到 iOS Universal Framework 就可以把你常用的元件分割成為獨立的 binary ,輕鬆重用了。

現在我會把一些自家的獨立元件,以及一些常用的第三方元件 (如 ASIHTTPRequest) 包成 framework ,這樣需要用的時候只需將他們拖放到專案中,不需要擔心 framework 版本和編譯問題了。

P.S.

當然了,無論用以上哪一個方法,所有的源碼和外加 framework 也應該加進專案的版本管理系統中。

如果用 1 或 2 的方法就應該用 git submodule 的方法確實記錄 library 的版本和位置,用 3 就直接 commit 和記錄使用的版本。如果是自己可控制的 framework ,最好加進自己的 version 進 header 或 api 上。

如果 Objective-c 也有像 ruby 的 gems 或 bundler 那有多好?

延申閱讀

Teagueduino 開箱

| Comments

早前在 KickStarter 見到 Teagueduino 項目,覺得蠻有趣所以參加了一份,今天產品到手了。

Teagueduino 是基於 AT90USB1286 的 Kit。跟 Arduino 很相似,只是它的定位在更加入門的用家:

  • 用定制的 IO Pin,像 socket 一樣插入底板。好處是比較簡單,不用像 Arduino 那樣拉線和用面包板,但自然沒有像 Arduino 那麼有彈性。
  • 十分圖像化的 IDE ,這很有趣,值得多講一下:

  • 圖像化顯示輸出輸入的水平和 Variable 的數值

  • 用 Click and Select 的方式編程,它會顯示所有 option。
  • 簡單,不懂編程的人也可以玩。但對於會編程的人來說非常不便,而且可以做的也明顯比 Arduino 的少。
  • Arduino 的背後是 C,你會遇到 compile 、header 問題,但 Teagueduino 完全隱藏了這些事。
  • 這也意味著 Teagueduino 上如果有新的 device 大概不太可能像 Arduino 直接插進去加新 library 就跑得動

因為這幾個月也入手了 Arduino 和讀了幾本書,Ardunio 其實已相當簡單易用,Teagueduino 的易用沒有甚麼優勢。但 Teagueduino 的 IDE 的強項在 Sharing。在 IDE 裡你可以直接看到 community 的 project,直接 clone 一個來做實驗。因為那些 IO 你都已在手,要跟著做出來比 Arduino 那種要下載 project 再執藥更簡單。有新的東西再 share 回 community 也很簡單。

最後,試試這個開箱後的第一個 Project (完全沒真正的編程的份兒,只是插些線而已 XD )

以上就是我的開箱報告,看看以後會做甚麼出來玩吧 :)

Upgrade to Rails 3.2

| Comments

Rails 3.2.0.RC1 已釋出

把現有專案升級到 Rails 3.2 只需更新 Gemfile:

1
2
3
4
5
6
gem 'rails', '3.2.0.rc1'
group :assets do
  gem 'sass-rails',   '~> 3.2.0'
  gem 'coffee-rails', '~> 3.2.0'
  ...
end

接著執行 bundle update 更新 Gemfile.lock。

在 heroku 上要用 git 去拿 pre 的 gem:

1
2
3
4
5
6
gem 'rails', '3.2.0.rc1', :git => 'git://github.com/rails/rails.git', :branch => "3-2-stable"
group :assets do
  gem 'sass-rails',   '~> 3.2.0', :git => 'git://github.com/rails/sass-rails.git', :branch => "3-2-stable"
  gem 'coffee-rails', '~> 3.2.0', :git => 'git://github.com/rails/coffee-rails.git', :branch => "3-2-stable"
  ...
end

3.2 最重要的更新是改良了 development 模式,只會 reload 更改了的 class ,這會讓 reload 大大加速。另一個重要的更新是自動在 activerecord 遇到慢 query 時 explain plan 並記錄,這對找出瓶頸很有用。完整的 changelog

用 Vagrant 快速建立開發環境

| Comments

這次要談談如何建立開發環境。

理想的開發環境

如果你曾經做過一些十人以上、持續一年以上的專案,你就會知道開發環境的重要性。我以前就待過一個專案:專案有 J2EE Server、RDBMS 還有外部的 legacy 系統。雖然開始時很好地設定了 Development、UAT 和 Production 環境,但經歷漫長的開發和改版,Development 環境的資料總是爛的:

  • 一些被改動到不合 constraint 的資料
  • 一些設定是錯誤的
  • 有時缺少了重要的 Data
  • 沒有運行的 server 或 backend job
  • 開發者的錯誤會讓 DB 或 Apps 全爛了,整隊人得花一天以上等待修復。。。

在開發的時候,我們需要的是一個快速建立、可以重現、一步到位而且每個開發者獨立的開發環境。這時候 Vagrant 就可以幫到我們了。

30 秒內學會使用 Vagrant

Vagrant 是一個 ruby 寫的工具,它是一個 DSL 讓開發者可以輕易控制 VirtualBox 的 VM 。用它可以輕鬆管理和制作我們理想中的開發環境。

如何使用 Vagrant?假設你已安裝 ruby 和 VirtualBox,安裝 Vagrant 很簡單:

1
2
3
4
$ gem install vagrant
$ vagrant box add ubuntu http://files.vagrantup.com/lucid32.box
$ vagrant init ubuntu
$ vagrant up
  1. gem install vagrant 安裝 vagrant
  2. vagrant box add 安裝新的 Vagrant Package。這裡的 ubuntu 是一個預先做好的空的 ubuntu 10.04 。
  3. vagrant init ubuntu 在當前的位置建立一個 ubuntu VM
  4. vagrant up 啟動 VM

就這樣 Vagrant 就設定好一個基本的 VM,並將當前目錄映射到 VM 的 /vagrant 之上。通常Vagrant Box 也會把 sudo 設為不用密碼,在開發時這會省許多事。

當然了,只有一個空白的 VM 沒甚麼用。Vagrant 可以做到的事有更多。

設定和包裝自己的 VM

Vagrant 已設定好 SSH,只要使用指令 vagrant ssh 就可以連線進 VM。

你可以 SSH 進去當普通的 VM 一樣設定系統,如安裝 language 、runtime 、library、database server 、memcached 、web server 等等。

Vagrant 支援自動化設定 VM ,你可以用 old school 的 shell script ,或者用 Chef 或 Puppet 自動化設定系統。Chef 和 Puppet 有許多深入的用法和設定,你要到他們的網站研究才行。如果我的情況,人手 ssh 進 VM 設定就夠用了。

好了假設你己安裝好開發環境,因為你主機的當前的目錄已映射到 /vagrant ,如果你當前目錄是 rails project ,你只需修改 config.xml 再 rails s 就可以享受成果了。

當你確認開發環境無誤,只要用指令 vagrant package 就可以將整個環境打包成 package.box 。放到網路上,其他人就可以用 vagrant box add the-url 指令安裝你的開發環境。

自訂 Vagrant Box

在 vagrant init 的時候,Vagrant 會建立一個設定檔 Vagrantfile:

1
2
3
4
Vagrant::Config.run do |config|
  config.vm.box = "base"
  # config.vm.forward_port "http", 80, 8080
end

vm.forward_port 會讓 vagrant 把 VM 的 port forward 到主機之上,我會設定如下:

1
2
3
4
5
6
7
8
Vagrant::Config.run do |config|
  config.vm.box = "base"
  config.vm.forward_port "rails", 3000, 3000
  config.vm.forward_port "mongo", 27017, 27017
  config.vm.forward_port "mongo-http", 28017, 28017
  config.vm.forward_port "redis", 6379, 6379
  config.vm.forward_port "memcached", 11211, 11211
end

這樣 VM 的 server 就可以在主機存取,而在 VM 3000 port 行的 rails 也可以在主機用 localhost:3000 看到效果。

有時候我們需要進一步設定主機,例如行一些 migration 或更新資料,我們可以用 Vagrant 的 provisioning 行 shell script:

1
2
3
4
5
Vagrant::Config.run do |config|
  config.vm.box = "base"
  config.vm.provision :shell, :path => "test.sh"
  config.vm.provision :shell, :inline => "echo foo > /vagrant/test"
end

之後在 vagrant up 或 vagrant reload 時,VM 就會自動執行那個 shell script 了。Vagrant 還有很多的設定,請細閱他們的 Tutorial。但只是以上的基本,相信已經可以避免許多因為開發環境的杯具了。

如果你還在共用開發環境,或在開發的 mac 上裝上不同版本的 mysql, mongodb, couchdb, memcached ,不妨試試用 Vagrant 簡化你的工作流程吧!

補記 (12-21-2011)

Vagrant 可以在 Windows 下使用。如果是 32 bit Windows 可以用 Ruby Installer的 ruby。如果是 64 bit Windows 則注意要用 1.8.7 的 64 bit JRuby

Heroku Gotcha

| Comments

今天把新 project 推上 heroku ,發現如下錯誤:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
-----> Heroku receiving push
-----> Ruby/Rails app detected
-----> Detected Rails is not set to serve static_assets
       Installing rails3_serve_static_assets... done
-----> Configure Rails 3 to disable x-sendfile
       Installing rails3_disable_x_sendfile... done
-----> Configure Rails to log to stdout
       Installing rails_log_stdout... done
-----> Gemfile detected, running Bundler version 1.0.7
       Unresolved dependencies detected; Installing...
       Using --without development:test
       You have modified your Gemfile in development but did not check
       the resulting snapshot (Gemfile.lock) into version control
       
       You have added to the Gemfile:
       * therubyracer (>= 0.9.8)
       * libnotify
       * rb-inotify
       
       You have deleted from the Gemfile:
       * growl
       * rb-fsevent
       FAILED: http://devcenter.heroku.com/articles/bundler
 !     Heroku push rejected, failed to install gems via Bundler

當然我有一個已更新的 Gemfile.lock 了。看看訊息中的 gems ,再看回 Gemfile 中相關的設定:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
group :development do
  gem "guard", ">= 0.6.2"
  case HOST_OS
    when /darwin/i
      gem 'rb-fsevent'
      gem 'growl'
    when /linux/i
      gem 'libnotify'
      gem 'rb-inotify'
    when /mswin|windows/i
      gem 'rb-fchange'
      gem 'win32console'
      gem 'rb-notifu'
  end

  gem "guard-bundler", ">= 0.1.3"
  gem "guard-rails", ">= 0.0.3"
  gem "guard-livereload", ">= 0.3.0"
  gem "guard-rspec", ">= 0.4.3"
  gem "rails-footnotes", ">= 3.7"
end

已經猜到是因為 heroku 自動查證 gemfile 時沒有考慮到 case 裡面的 OS。再搜尋 SO 可以看到類似的症狀。

解決方法?開一個新 branch ,在裡面把 Gemfile 修正,移除 heroku if/case 相關的 gem,再上傳這個 branch 做 heroku master即可。