avatar

大兜

右手寫程式,左手寫音樂

留言

Rails 購物車設計

封面圖片為 Minecraft 遊戲的截圖,軌道上的貨車(cart on rails),筆者也算是從 alpha 版就開始玩的老玩家呢。

隨著電子商務的崛起,網站上的購物車系統已經成了普遍的功能,這幾年 Rails 在台灣也快速竄紅,且由 Dave Thomas 與 David Heinemeier...

繼續閱讀

留言

平凡人出國夢

六月去了一趟沖繩,這是第一次不是因為工作或是演講而出國,保持多年的「從沒出國玩過」的紀錄就這麼被破除了,高興之餘卻有些小可惜,畢竟再不能以炫耀式的語氣聲稱自己出國從沒有花過錢了。

遙想兒時出國對筆者而言曾是高不可攀的夢想呢,那時全家都沒有人出過國,畢竟這種娛樂對家裡來說是個不小的負擔。幸...

繼續閱讀

留言

台灣身份證字號驗證器

今天在 Ruby Taiwan 的 FB 社團上看到 adz 大大在問是否有身份證字號驗證的 gem 可以用。

這東西記得在大一時用 C、Java 各寫過一次,程式碼已遺失,反正今天寫了一天程式也累了,只好寫別的程式來放鬆一下(啥?),不過這次會用 Ruby 來寫,同樣的程式碼我也放在 Gist

繼續閱讀

留言

TJDict 兩週年紀念

其實算起來兩週年是去年八月,現在發這篇有些晚,筆者寫此文前已先懺悔一番。

說來那話兒也不長⋯⋯

2012 八月,筆者還是個飽受英文論文所苦的死大學生,總是開一堆字典交叉查詢覺得很不方便,索性做了一個工具幫助自己,本來是自用,但在朋友慫恿下放上了 Google...

繼續閱讀

留言

ConFoo 2015 心得

ConFoo.CA 2015

到頭來出國從不為了玩的黃金紀錄仍然保持住了,真傷腦筋啊。

去年,筆者在 Ruby 官方網站看到了加拿大 ConFoo 在徵 Ruby 的稿件,雖然蒙特婁有些遙遠,不過講者享有交通與食宿全免的福利(住在希爾頓酒店),筆者遂小投三篇,結果運氣不錯地上了兩篇。按照上一篇 Ruby Kaigi 的慣例,先來秀個徽章吧 =)

ConFoo 2015 Speaker

這次的旅程對筆者來說有需多值得紀念意義,並且刷了許多「第一次」成就:

  • 路過北京、上海
  • 轉機經驗
  • 到西方國家
  • 自己規劃出國
  • 體驗零下 -15 度、下雪、堆雪人

但要說收穫最多的,是筆者終於在死前克服了搭飛機的恐懼,非指懼高症,而是對於流程的不安與緊張感,就像小時候時第一次自己搭火車一樣,從月台買票到進入月台到上對火車,即便去年有去日本的經驗,筆者仍然對於流程非常陌生,而這次來回總共搭了六台飛機,不想熟悉也難。

另外此趟只有損失零錢包與手機,比預料中的情況要好很多,希望下次出國可以挑戰無損歸國。只是不知道三月當了上班族後,是否還有時間可以參與議程,有點可惜。

ConFoo.CA

ConFoo 是加拿大蒙特婁每年冬天的大型研討會之一,慣例辦在希爾頓酒店,主題以 Web 技術為主,前身是 PHP 研討會,這幾年才轉為綜合的研討會,這也是為何筆者有機會赴加拿大講 Ruby。

此外門票約 3 萬台幣左右,3 天 9 軌,141 場講題,88 位講者,且每晚有免費的派對。即便門票如此,還是有接近千位聽眾報名,且無論從講題安排、派對活動、場地、飲食都是個品質很高的研討會。

建議有興趣的人可以明年投稿看看,大會主辦這幾年開始想將研討會轉型為國際研討會,很歡迎外國人,例如今年除了筆者為台灣代表之外,也有來自沙烏地阿拉伯的講者。至於聽眾除了北美,也有南美與歐洲各國的人來參與,你可以很容易的與世界各地的工程師們交流、分享彼此的知識。且大多人都相當友善又樂於交友,氣氛很融洽。

跟台灣的研討會比較

比較筆者過去在台灣參與的研討會,ConFoo 的設計有些很有趣的巧思,例如在名牌上加上 QR code,如果會眾沒有攜帶名片,可以讓別人的手機掃條碼,而條碼內容就是當初會眾報名研討會時所輸入的社交網址。即便筆者沒有智慧型手機,這個功能還是很吸引人。

此外除了 9 個講聽以外,有一間最大的會場是預留給社交之用,內有很多桌椅,而每張桌子上面會標有某種特別的技術或領域的牌子,例如 PHP、Ruby、Maching Learning、AWS 等,會眾可以透過入座該位子,輕易找到與自己有相同興趣的人交流。

會後小心得

筆者這次的主題是 Ruby 上的 C 擴展以及去年在 Ruby Kaigi 講的 Sony Remote Camera API,但可能是個 Web 技術研討會,來聽我的講題的人沒有很多。整個研討會中,光是 PHP 與 Java 的網站應用主題就超過了 7 成,而 C 的主題看過去也只有一場(就是我的),所以看來 ConFoo 要真正從 PHP 研討會歷史中脫出,還需要幾年的時間。

此外不免小感嘆一下,在台灣不知道除了 godfat 以外,是否有寫 Ruby 的人是拿來做 Rails 以外的應用的,很想認識與交流一下。這年頭就連 PTT 上的 Ruby 版也淪為了 Rails 版,Ruby 論壇成了 Rails 論壇,有些小可惜呢。

繼續閱讀

留言

2014 回顧

好漂亮的雞毛撢子

時間 工作 成就 日常
四月 成立五倍紅寶石股份有限公司 擔任 RubyConf Taiwan 講者、與 Matz 合影 住的地方從 8 坪進化到 30 坪第一次組衣櫃
五月      
六月     買了這輩子看過最大的電視(55 吋)
七月   花蓮五日遊,實驗白天旅行,晚上工作的可行性 世足通宵派對
八月      
九月   擔任 Ruby Kaigi 講者、第一次搭飛機、第一次去日本 烤肉團
十月      
十一月     25 歲慶生會、開始留鬍子
十二月 與五倍紅寶石拆夥 TJDict 上了 freeGROUP,使用人數衝破 17k 湯圓大會、聖誕晚會、跨年派對、PS4 派對

感覺今年沒什麼在工作,只有在玩樂啊XD

不過確實自從有客廳和客房之後,家裡三不五時會有聚會。雖然遠了點,至少有一個同樂地方可以吵再晚都沒有人管,且從家徒四壁到現在有電視機、遊戲機、桌遊 6 款、烤箱、沙發床等,明明只有一個人住,室內拖鞋也莫名其妙增加到 4 雙,平時沒去注意,但突然想起來真的覺得頗誇張的XD

來看一下去年的 2013 回顧的沒有完成的目標:

  • 帶全家出國玩
  • 寫書
  • 投稿,並且錄用至少一個研討會

沒有錢和時間帶全家出國去玩,但有投稿了 RubyConf Taiwan 與 Ruby Kaigi,並且幸運的錄取了,且 2015 的加拿大 ConFoo 也錄取了筆者兩篇講題,雖然今年業績只有一半,但投稿的目標比預期多出了數倍的績效。

寫書方面還是沒有完成,不過筆者在 2014 最後一天交出了兩百頁的內容到出版社,以為可以告一段落,想不到還有很多需要修改。但運氣好的話,應該 2015 可以出版吧?

最近因為與五倍紅寶石拆夥,又回到找外包的生活。目前規劃今年把兵役搞定,然後 2016 可以準備出國工作,至於順利與否,且看老天爺XD

2015 我來了 :)

繼續閱讀

留言

Rails 4.2 重點介紹

Rails 團隊終於要在聖誕節的同時釋出 Rails 4.2 版了,這次更新的重點有以下項目:

  • Active Job
  • Asynchronous mails
  • Adequate Record
  • Web Console
  • Foreign key support

Active Job

一個網站常有些較繁重的工作,並不希望在使用者提出請求時立即執行,以寄出一萬封信為例,這也許需要幾分鐘的時間,當使用者點下寄信按鈕時如果還需要等個幾分鐘才可以看到回傳頁面,這將造成糟糕的使用者體驗。

正規的作法是將這類需要長時間的工作丟到工作佇列去排程,並在背景中執行多個 worker 程序,每個 worker 都會不斷重複從佇列中取得新的工作去執行。

Rails 已經有許多 gem 可以解決這個問題,著名項目包括 ResqueSidekiqDelayedJob,其中 Resque 與 Sidekiq 使用 Redis 存放工作住列,DelayedJob 則用關聯式資料庫。

Active Job 並不是提出了一個新的實作,換句話說,使用 Rails 4.2 並不代表未來就不用安裝 Resque 之類的 gem。

它的真正意義在於統一使用介面,讓開發者在不同的 gem 之間切換時,可以不用受到 gem 的不同 API 而影響,因而降低重新改寫的成本。

看到這裡是否覺得這種作法很熟悉?它其實就是適配器模式(Adapter pattern),早在 Active Record 誕生的時候就已經使用相同的技巧,Rails 之所以能以相同的 API 介面在不同的資料庫之間遊走也是拜此所賜。

目前支援的 gem 有:

$ ls -1 activejob/lib/active_job/queue_adapters
backburner_adapter.rb
delayed_job_adapter.rb
inline_adapter.rb
qu_adapter.rb
que_adapter.rb
queue_classic_adapter.rb
resque_adapter.rb
sidekiq_adapter.rb
sneakers_adapter.rb
sucker_punch_adapter.rb
test_adapter.rb

除了 test_adapter.rb 僅用於測試,以及 inline_adapter.rb 為預設(立即執行,不會丟入背景),以外都有相對的 gem 需要安裝。

使用方式

工作的內容必須定義在 app/jobs/ 下,並繼承自 ActiveJob::Base,不過 Rails 4.2 提供了產生器,並不一定要手動新增:

$ rails g job execute_simulate
      invoke  test_unit
      create    test/jobs/execute_simulate_job_test.rb
      create  app/jobs/execute_simulate_job.rb
# app/jobs/execute_simulate_job.rb
class ExecuteSimulateJob < ActiveJob::Base
  queue_as :default

  def perform(*args)
    # Do something later
  end
end

queue_as 可以設定將此工作排進特定的佇列,預設是 default,可以透過 --queue
參數修改:

$ rails g job execute_simulate --queue urgent

使用起來像是這樣:

# 將工作丟進佇列
ExecuteSimulateJob.perform_later record

# 排程明天中午再執行
ExecuteSimulateJob.set(wait_until: Date.tomorrow.noon).perform_later(record)

# 排程一週後執行
ExecuteSimulateJob.set(wait: 1.week).perform_later(record)

# 指定特定的佇列
ExecuteSimulateJob.set(queue: :important).perform_later(record)

設定要使用的 gem:

# config/application.rb
module YourApp
  class Application < Rails::Application
    # 請確保 Gemfile 已經有安裝所要使用的 gem
    config.active_job.queue_adapter = :resque
  end
end

回呼(Callback)

共有以下 6 個註冊點:

  • before_enqueue
  • around_enqueue
  • after_enqueue
  • before_perform
  • around_perform
  • after_perform

使用方式與 controller、model 中的回呼寫法是一樣的:

class ExecuteSimulateJob < ActiveJob::Base
  queue_as :default
 
  before_enqueue do |job|
    # 在佇列前執行
  end
 
  around_perform do |job, block|
    # 在工作開始前執行
    block.call
    # 在工作完成後執行
  end
 
  def perform
    # Do something later
  end
end

Asynchronous Mails

如果寄信工作也要丟到工作佇列,先別急著寫工作檔,Rails 4.2 的 Action Mailer 內建了 DeliveryJob 類別,並提供 deliver_later 方法將寄信工作推進佇列。

你可以像這樣使用:

# 使用 #deliver_later 透過 DeliveryJob 來寄信
MyMailer.welcome(@user).deliver_later

# 若不想丟到工作住列,也有 #deliver_now 可以使用
MyMailer.welcome(@user).deliver_now

Adequate Record

由 Aaron Patterson 所作,用於提高 #find#find_by 等一些常用查詢指令的速度,可以提升 Active Record 約莫兩倍的效能。

主要是因為 Active Record 在產生 SQL 過程有很多重複的片段不斷被重新製造,這其實可利用快取將重複的片段保存起來。細節請參考 Aaron Patterson 的網誌

Web Console

如果你有用過 better_errors gem,那麼這就是類似的東西了。Rails 4.2 在開發環境下的錯誤頁面會多出一個 rails console 命令窗可以使用,除了一般 irb 的功能以外,也可以存取到該次請求中定義的實體與區域變數。

Rails 4.2 Web Console

但不只有錯誤頁面才有命令窗可以使用,也可以在任何 view 的檔案中的任何位置加入 <%= console %>,只要渲染到該檔案,就有命令窗可以使用。

外鍵(Foreign Keys)

Rails 4.2 遷移指令支援了 SQL 的外鍵定義功能,目前只有 mysql、mysql2 與 postgresql 可用。

# 將 `articles.author_id` 定義為參考 `authors.id` 的外鍵
add_foreign_key :articles, :authors

# 若命名沒有按照慣例,也可以透過設定達到
# 例如將 `articles.author_id` 定義為參考 `users.lng_id` 的外鍵
add_foreign_key :articles, :users, column: :author_id, primary_key: "lng_id"

# 刪除 `accounts.branch_id` 外鍵
remove_foreign_key :accounts, :branches
 
# 刪除 `accounts.owner_id` 外鍵
remove_foreign_key :accounts, column: :owner_id

這個功能在 migration 與 model 等會產生遷移檔的產生器,當使用到 references 型別時也會自動的被使用,例如:

$ rails g migration add_user_to_posts user:references
      invoke  active_record
      create    db/migrate/20141222180048_add_user_to_posts.rb
class AddUserToPosts < ActiveRecord::Migration
  def change
    add_reference :posts, :user, index: true
    add_foreign_key :posts, :users # Rails 4.2 功能
  end
end
繼續閱讀

留言

RubyKaigi 2014 攻略心得

Ruby Kaigi 2014

這輩子截至目前為止出國好像都還不是為了玩,不知幸也不幸。

若說去年是接案維生的一年,今年就是演說生涯的起點吧?自四月的 Ruby Conference Taiwan 擔任講者之後,投稿了日本的 Ruby Kaigi,最後幸運的被錄取了,遂有了這次的出國經驗。

官方網站

大會的

繼續閱讀

留言

C 語言之多行巨集

有時候我們在翻閱原始碼的時候會看到類似這樣的寫法:

#define FOO(x, y)    \
do {                 \
  typeof(x) tmp = x; \
  x = y;             \
  y = tmp;           \
} while...
繼續閱讀