跳到主要內容

發表文章

【電子書】國家解剖學(Anatomy of the State)

這是一本憾動人心的小書,Murray N. Rothbard 的 Anatomy of the State,原書請至 Mises Institue 網頁免費下載或是購買,中文版也終於在每日辛苦翻譯後集結完成。

我把它翻成《國家解剖學》,先前我在《國家的故事》一文中曾經嘗試要討論的國家成長歷程,在本書中有 Rothbard 大師的完整推導,還加上各種值得深入閱讀的材料。

從國家的產生、國家的性質、國家的各種轉型變種、國家的盟友、國家慣用的蠱惑人心伎倆、國家與國家之間的互動,還有我們要怎麼對抗國家等,文章雖短,但卻字字珠璣,值得閱讀。

中文版與本站相同,同樣採用姓名標示的創用CC授權,內容若有任何翻譯失真,請以 email 與我聯絡以利討論修正,最後,若是這本中文版有激起任何火花,歡迎廣為散播,我個人更推薦有興趣的讀者,可到 Mises Institute 豐富的資料庫進行延伸閱讀。

下載 epub下載 mobi下載 pdf

更新紀錄:
2013/03/24:發表 epub/mobi 格式2013/04/07:發表 pdf 格式2013/04/27:修正 Adobe Digital Editions 開啟 epub 的亂碼問題
最近的文章

在 RSpec 裡測試 Rake Task

最近被 Rake Task 的測試設定搞得一頭霧水,簡單記錄一下測試 Rake Task 的測試設定,以及各種鬼打牆的血淚史:
TL;DR為了避免各種 task 載入、執行狀態等相互干擾導致 test case 會偶發性失敗,每一次執行 test case 時就去做「載入」、「卸載」會比較沒有鬼打牆狀況出現。# spec_helper.rb config.before(:each, rake: true) do Rails.application.load_tasks end config.before(:each, rake: true) do Rake::Task.clear end 把 Rails.application.load_tasks 放在 before(:each) 確保每次載入 test case 前都有正確 load 到要測試的那隻 task ,並在 after(:each) 時用 Rake::Task.clear 去清空剛剛載入的 Rake Task。透過 rake: true 這個 flag 可以避免其他不相關的單元測試也去載入 Rake Task。透過每個 each 都做載入跟卸載 Rake Task 後,就可以在 test case 單純使用 Rake::Task['task_name'].invoke 來手動執行 Task 而不用另外去作載入或卸載。# spec/lib/tasks/example_task_spec.rb require 'rake' describe 'example_task test', rake: true do ... it 'does something' do Rake::Task['example_task'].invoke expect(result).to eq(something) end end 血淚史之所以最後還是決定要每次 test case 就去載入,實在是因為太常出現鬼打牆的狀況了:單一檔案裡 Rake::Task 只能被 invoke 一次有多個需要 invoke 的 task 時就會有些 example 沒能成功執行 task之前寫 Rak…

【工具】Kindle "My Clippings.txt" 的轉檔 gem KCFU

Kindle 的剪貼簿功能雖然在 Kindle 上很好用,但真的要抽出來另外處理塞到部落格充當文章書摘的時候還真的麻煩,因為 My Clippings.txt 就是一個很簡單的純文字檔,每次在 Kindle 上面 hightlight / bookmark / notes 時就會依照書的 title 去新增一段特定格式的文字段落,所以如果同時看很多本的時候,打開 My Clippings.txt 會發現裡面就依照 clippings 時序夾雜著來自不同書裡的內容,得再經過一些處理才能分成不同的來源。

原先有找到 firewood 這個套件,不過沒辦法在我的電腦上使用 QQ,乾脆就自己刻個輪子吧。

GitHub 上面的 kindleclippings 是用 Ruby 寫的,簡單又方便使用,站在小巨人的肩膀上刻了一個 kcfu 來做基本的拆分檔案,另外加配了一個陽春的 Markdown 格式轉換器方便做書摘。

最簡單的用法是開一個資料夾,把你的 My Clippings.txt 放到裡面,再寫個小 Ruby 檔:
# kcfu.rb require 'kcfu' parser = Kcfu::FileUtil.new parser.parse_file(File.expand_path("#{File.dirname(__FILE__)}/My Clippings.txt"), convert: :markdown) 然後安裝 KCFU(沒有安裝 Ruby 的同學若要服用請先安裝 rbenv 跟 ruby )
gem install kcfu # Under folder of your kcfu.rb and 'My Clippings.txt' file ruby kcfu.rb 就搞定了。

【書摘】Soft Skills: The software developer's life manual

公司前輩分享了 Soft Skills: The software developer's life manual 這本書,後來又在 Soft & Share 看到推廣介紹,抱著當休閒讀物的心情來閱讀是很不錯的。

作者 John Z. Sonmez 在這本書中想要涵括的內容實在包山包海,如果對於人生迷惘的捧油,的確只要看了這本書所簡單介紹的內容就大概可以對人生重拾一些希望,也能循著這些主題繼續往深探索。比較特別的是,每個章節的篇幅被設計成大概一篇 Blog 文長度,所以閱讀起來的節奏感很是不錯,即使有些主題令人打哈欠,有些主題不斷地出現各種課程推銷,但都還能在睡著與失去耐心之前看完一個段落,這點是很值得效尤的閱讀設計技巧。

討論的主題分成七大部分:

Section 1 - Career / Section 2 - Marketing Yourself
這兩部份討論的事情差不多,主要觀點是:把自己當成事業經營。

每個人的人生想成就的事物不盡相同,但大致上不出「創業」、「職員」、「自由工作者」這三種工作型態,每種工作型態都有其優缺點,沒有最好的選擇,只有最適合、最自在的選擇。制定目標的技巧:由大至小,先抓大方向,然後再去規劃要怎樣分階段性地往大方向前進,在執行計畫目標的過程當中,也不斷地去重新思考「目前的走向」是不是在往「想要的目標」前進,不斷地修正、不斷地思考,減少瞎忙的狀態。

每個人的人生想成就的事物不盡相同,但大致上不出「創業」、「職員」、「自由工作者」這三種工作型態,每種工作型態都有其優缺點,沒有最好的選擇,只有最適合、最自在的選擇。制定目標的技巧:由大至小,先抓大方向,然後再去規劃要怎樣分階段性地往大方向前進,在執行計畫目標的過程當中,也不斷地去重新思考「目前的走向」是不是在往「想要的目標」前進,不斷地修正、不斷地思考,減少瞎忙的狀態。

把自己當成事業經營,適當時候要勇於承擔風險,即使是受僱,心態上也應該將工作表現視為擦亮自己「工程師專業」這塊招牌的方法之一。心境不同,面對困難的態度也會有所不同。

除了砥礪自己的正直人格之外,也要適當地行銷自己的工作能力,名聲資產的累積管道除了被動地讓共事的同事發掘之外,可以積極地利用自媒體增加自身技術能力的曝光度,對公司內部分享技術心得、寫 blog 文章、參與 open source 專案、錄製 yout…

在 Trailblazer 的 Policy 中透過客制 Exception 來處理複雜的「錯誤回應」

為了盡量貼近 Trailblazer 的設計概念,許多原先會透過 Controller before_action 去處理的權限管控,盡量都搬進 Trailblazer 的 Policy 裡。

Policy 採用類似 Pundit 的語法,典型的 Policy 如下:
class Thing::Policy def initialize(user, thing) @user, @thing = user, thing end def create? (admin? || approved?) && @thing.persisted? end private def admin? @user.admin == true end def approved? @user.is_approved end end 在 Operation 中若要調用這隻 Policy 的話要宣告:
class Thing::Create < Trailblazer::Operation builds -> (params) { dispatched_class_accroding_to(params) } def self.dispatched_class_accroding_to(params) Thing::Create end include Trailblazer::Operation::Policy policy Thing::Policy, :create? def process(params) validate(params[:thing]) do |f| f.save end end end Operation 在 controller 裡被 call 的時候,會先跑 builds 去回傳 Operation 類別,此時,正是個機會去依照 params 內容 dispatch 到其他的 Operation 去,改天再分享利用 builds 簡化路由的實作。

透過 builds 確認 operation 後,所有的參數會先經過 setup!(params) > setup_params!(param…

初探 Trailblazer 框架

最近公司的 Rails 專案試用了 Trailblazer 這套整理 Rails 程式碼的框架。(目前使用的是 1.1 版)

Trailblazer 是擺在 Rails 上的一套工具,雖然有本專書可以翻找,但實際上就是個自成一格的整理程式碼套路,除了要學新的 DSL 外,在 API 文件沒有寫得非常詳細,加上使用者也沒多到可以 stackoverflow 的情況下,假如開發需求和設計者 Nick Sutterer 設想的情況不一樣時,小小撞牆是難免的。

Trailblazer 是模組化設計,所以並非所有模組需要安裝才能開始享受 Trailblazer 帶來的方便感,除了主要的 Operation / Policy / Contract / Cell 等稍微有摸過外,其他的眉眉角角尚待開發。稍微整理一下截至目前為止使用這套框架的個人認知,這套 Trailblazer 的目的是將原先 Rails 單純 MVC 架構下可能會散亂在 Controller / Model 層的商業邏輯,集中起來包在 Operation 的概念裡,(在理想狀況下)分別簡化日益肥大的 Controller / Model / View 邏輯:
Controller 讓 controller 單純負責傳送 current_user / resource 到正確的 operation 並視操作結果導向相對應的路由權限控管交給 Policy 處理,用 controller 塞給 operation 的 current_user 配合 operation 的 model!(param) method 所傳回之 resource 兩者之間的關係去做權限控管商業邏輯封裝在 Operation 裡只傳送成功執行 operation 後的 @model (resource) 給 viewModel 讓 Model 單純負責與資料庫之間的溝通,原先的 Validation 改由 Contract 操作本來可能塞在 Model 裡的各種 before_validationbefore_save 等 callbacks 拉出來改在 operation 的 process 裡面操作本來塞在 “fat model” 裡的商業邏輯,一樣抽出來寫在相對應的 operation 裡View 減少原先直接吃 cont…

【筆記】Practical Object-Oriented Design in Ruby (POODR)

Practical Object-Oriented Design in Ruby (POODR) 不會很厚,循序漸進地介紹物件導向設計的各種重要概念,而且範例用的是 Ruby 來解說,挺親切的。

除了各種設計原則之外,也簡要解釋了 Inheritance / Module / Composition 的使用時機與差異。

最後一章介紹測試原則,除了說明一般的測試原則之外(例如主要應測試 public interface / incoming message / outgoing command ),也很清楚地說明要怎樣去分別把不同的測試責任分在 module / test double / test class 上,以及讓 test double 與實際的程式碼同步的技巧,可以反覆閱讀的參考書。

利用 find_in_batches 在 Rails 做跨資料庫的資料移轉操作

在處理跨資料庫搬動並且需要一筆一筆資料去做各種運算處理時,最直覺的方式,是把表格裡的所有資料通通透過 ORM 撈到 ActiveRecord::Association 陣列裡,再用 each 去做操作:
User.all.each do |user| user.email = "assign@new.email" ... end 但由於 Rails 會需要先去建立這些 objects,如果資料筆數很多的話,一次通通撈出來會佔用過多不必要的記憶體,可以使用 find_in_batches 做批次處理,減少系統 RAM 的負擔。
User.find_in_batches do |group| group.each do |user| user.email = "assign@new.email" ... end end 但如果要做跨資料庫的處理時,需要特別安插 ActiveRecord::Base.establish_connection 讓 Rails 知道當前操作需要連到哪個資料庫,舉例而言,假如想把資料一批一批從 :origin 調出來,然後檢查、編輯以後塞到 :migrated 資料庫裡,那麼需要在 Query 前去告訴 Rails 目前要連到哪個資料去撈資料:
# Tell rails to get data from :origin ActiveRecord::Base.establish_connection :origin User.find_in_batches do |group| group.each do |user| # user variable here are the user object that Rails queried from :origin DB and initialed # Tell rails to switch connection to :migrated for data manipulation ActiveRecord::Base.establish_connection :migrated migrated_user = User.find_by_email(user.email) ||…