高見龍

iOS app/Ruby/Rails Developer & Instructor, 喜愛非主流的新玩具 :)

Ruby 語法放大鏡之「如果想要找某個方法的定義,該怎麼找?」

Ruby 語法放大鏡」系列短文主要是針對在大家學習 Ruby 或 Rails 時看到一些神奇但不知道用途的語法介紹,希望可以藉由這一系列的短文幫大家更容易的了解到底 Ruby 或 Rails 是怎麼回事。

在寫程式的過程中,如果遇到某個方法不會用或不知道該傳什麼參數怎麼辦? 不要急著翻 Google 或 Stackoverflow 網站,先翻官方的使用說明手冊吧,RTFM 是最好的方法!

除了翻手冊之外,像 Ruby 或 Rails 這樣 open source 的工具,另一個好方法就是直接翻它的原始碼出來看,看看它是怎麼實作的。

原始碼挖挖挖!

在開發 Ruby / Rails 專案時,通常我遇到一些很有趣或很有點厲害的寫法,就會想挖出來看看它是怎麼做的。直接開 Rails Console 來試一下:

1
2
3
4
5
$ rails console
Loading development environment (Rails 5.0.0.beta3)

>> 3.days.ago
=> Sun, 24 Apr 2016 09:02:02 UTC +00:00

3.days.ago 這樣就能印出三天前的時間,超方便! 但它怎麼做的…?

你可以使用 method 這個方法來回傳一個 Method 類別的實體,並且準備對它做一些操作:

1
2
3
# 我先用 method 方法取得 `days` 這個方法物件
>> 3.method(:days)
=> #<Method: Fixnum(Numeric)#days>

雖然「用 method 這個 method 回傳一個 Method 的實體」這句話唸起來超饒舌,但這個方法取得的物件還滿好用的,例如:

1
2
3
# 使用 owner 方法取得定義這個方法的類別或模組
>> 3.method(:days).owner
=> Numeric

看來是定義在 Numeric 這個類別或模組裡。使用 source_location 可以挖出檔案在哪:

1
2
>> 3.method(:days).source_location
=> ["/Users/user/.rvm/gems/ruby-2.3.0/gems/activesupport-5.0.0.beta3/lib/active_support/core_ext/numeric/time.rb", 45]

即然檔案路徑都有了,就可以去打開來看看是怎麼寫的了。但如果是 Ruby 內建的方法,就沒辦法直接取得原始碼的路徑,source_location 方法會回傳 nil:

1
2
>> method(:puts).source_location
=> nil

那怎辦? 例如想要知道陣列內建的 sort 是怎麼做排序的話,就去翻翻官方手冊吧。

連到官方手冊,跳轉到關於 Array 類別的 sort 章節:

image

除了介紹以及使用範例外,如果對原始檔有興趣,也可以點一下右上角的那個「放大鏡」,看看這個方法是怎麼用 C 語言實作的:

image

然後就可以再繼續追下去了。如果對 Ruby 的原始碼有興趣,也可在 Github 上取得完整的原始碼。連結

小結

曾有朋友問,要怎麼樣才能從新手變成比較資深的開發者。

除了官網的手冊要看之外,有空挖挖原始碼、讀原始碼,看看這些大大是怎麼做出這些功能進而吸收變成自己的經驗值,都是讓你可以更快變強的好方法 :)

Comments