[譯] 如何心平氣和地閱讀代碼

  1. 多寫代碼
  2. 多讀代碼
  3. 天天都完成以上內容

這是我在兩年前轉向編程時給我本身的要求。幸運的是,如今有不少在線編寫代碼的課程和教程能夠教你寫代碼,然而他們卻基本上都沒有去教你如何閱讀代碼。html

這是一個重要的區分點。隨着進入科技領域的編程訓練營畢業生數量的 飛速增加。強調閱讀源碼變得更加劇要。Brandon Bloom 寫道前端

若是它在 的機器上運行,它就是 的軟件。 應該對此負責,因此 必須對它瞭如指掌。android

Yes, you.

雖然每一個程序員都應該閱讀源碼,但 事實 並不是如此。許多程序員不肯意閱讀源碼是由於它閱讀起來很難,容易打擊他們的信心,而且讓他們感到本身很蠢。我知道,由於這就是個人感覺。ios

其實只是方法不對git

在我閱讀其餘人的代碼時,我想出了一個只須要三步的閱讀方法。可能有些人已經在遵循這些步驟,但我相信大部分人是沒有的。程序員

個人步驟以下。github

1. 選一個你感興趣的點

Image Source: [https://thenextweb.com/wp-content/blogs.dir/1/files/2010/04/twitter-location-300x200.jpg](https://thenextweb.com/wp-content/blogs.dir/1/files/2010/04/twitter-location-300x200.jpg)

回想我第一次閱讀源碼的時候,那簡直是一場災難。web

我當時正在學習 Sinatra,而後我想更好的瞭解底層運行機制。然而,我並不知道應該從哪裏開始讀,因而我找到了它在 Github 上的 repo 而後隨便打開了一個文件。不開玩笑,我確實是這樣作的。編程

我想我能夠花一個下午來研究它,而後在吃晚飯的時候就能夠徹底掌握。畢竟,閱讀我本身的代碼很容易,閱讀別人有什麼不一樣?後端

咱們都知道接下來會發生什麼。能夠這麼說,我當時的感覺像一頭撞在了一堵文字牆上同樣。

我一次想學的東西太多了。許多初學者在第一次閱讀源碼的時候也會犯一樣的錯誤。

心智模型是一點一點創建起來的,閱讀代碼也應該如此。

不要去試圖以堅持努力來消化 1000 行代碼,專一於一個主題。若是可以細化到單個方法更好。

有一個細化的焦點可以讓你分清什麼是相關的,什麼是不相關的。沒有必要去理會那些不相關的東西。

然而,選擇一個特定的主題並不能解決你的全部問題。知道它在代碼庫中的位置仍然是個難題。

這就是第二步的問題了。

2. 找到一個切入點

Image Source: [https://glenelmadventblog.files.wordpress.com/2012/12/loose-thread.jpg](https://glenelmadventblog.files.wordpress.com/2012/12/loose-thread.jpg)

如今你有了一個想要學習的目標,接下來應該怎麼作?

幸運的是,編程語言附帶了檢查工具。

對象的類,類的祖先,堆棧跟蹤,仍是某種方法的全部者,這是大多數語言都有的特性。不管你是想知道哪個,一旦你開始分析代碼庫,你會遇到一系列問題。

與其用文字來解釋這個概念,不如用代碼展現來得更快。

開始分析

假設我想學習更多 ActiveRecord 的相關知識。而後我已經把重點縮小到了 belongs_to 方法上,如今我想了解它如何影響 ActiveRecord 模型。

ActiveRecord 是 Rails 的一部分,它是用 Ruby 構建的。Ruby 提供了大量開發工具。

個人第一種方法是使用調試工具,好比用 pry gem 來剖析個人 ActiveRecord 模型。對於以前的假設,這就是我選擇調試的模型的代碼。

class Comment < ActiveRecord::Base
  belongs_to :creator, foreign_key: 'user_id', class_name: 'User'
  belongs_to :post
  binding.pry
  validates :body, presence: true
end
複製代碼

注意 binding.pry 語句。當 Rails 遇到這行代碼時,pry 將會在執行中期暫停應用程序並打開命令行提示符。

下面是我研究 belongs_to 關聯的時候在控制檯使用的示例交換。

  • 個人全部的輸入內容都是在 pry > 以後。

  • => 顯示控制檯的輸出。

pry> class = belongs_to(:post).class
=> ActiveRecord::Reflection::AssociationReflection

pry> class.ancestors
=> [ActiveRecord::Reflection::AssociationReflection,        
    ActiveRecord::Reflection::MacroReflection,
     ...omitted for brevity ]

pry> defined? belongs_to
=> "method"

pry> method(:belongs_to).owner
=> ActiveRecord::Associations::ClassMethods
複製代碼

若是你不太能理解 Ruby,而且這個交換讓你感到困惑,能夠看看個人提示。

  • belongs_to :post 運行時,它返回一個 AssociationReflection 類的實例。

  • MacroReflectionAssociationReflection 的父類。

  • belongs_to 是一個類方法,它是在 ActiveRecord::Associations 內部的 ClassMethods 模塊上定義的。

如今我有了一些線索,可是我應該遵循哪一條呢?由於我對 belongs_to 方法自己更感興趣,而不是它的返回值,因此我決定去查看 ClassMethods 模塊。

3. 跟隨線索

如今你已經有了想要跟隨的目標,剩下的就是跟隨它,直到找到你的答案。這彷佛是一個簡單的步驟,但這正是大多數初學者犯錯的地方。

其中一個緣由是,倉庫是沒有目錄的。咱們任由維護人員以可讀的方式組織他們的文件。

對於有不少維護者的大型項目,這一般不是問題。

但對於一個小項目,你可能會發現本身要費力地逐個處理文件,逐個破譯名稱變量,而後就會屢次遇到「這是從哪裏來的」的狀況。

GitHub 搜索

有一個工具能夠幫助咱們更容易完成這個任務,就是 GitHub 搜索(咱們假設你正在閱讀的項目是在 Github 上的)。Github 搜索很是方便,由於他可以顯示全部匹配搜索查詢的文件。它還能顯示符合查詢的內容在文件中的位置。

爲了獲得最好的結果,你須要讓你的搜索儘量具體。這須要你對你想找的內容有一個概念。盲目的搜索 Github 是沒有用的。

回到步驟 2 中的示例,我試圖在 ActiveRecord::Associations 中找到 ClassMethods 模塊。用外行人的話來講,我正在尋找位於 ActiveRecord 模塊內部的模塊 Associations 中的 ClassMethods 模塊。此外,我也在尋找 belongs_to 方法。


這是個人搜索查詢。

結果準確地顯示了我正在尋找的東西。

belongs_to method inside of ClassMethods

可能須要更多研究


Github 搜索將會顯著的縮小你的搜索範圍。所以,你能夠更容易的找到一個深刻代碼庫的切入點。

不幸的是,找到類或者方法不必定能給出問題的答案。你可能發現你從一個模塊跳到另外一個模塊,直到你瞭解全局。

在個人例子中,belongs_to 類把我導向了 BelongsTo 中的 build 方法。這讓我找到了 Association 的父類。

build method in BelongsTo class

build method in Association class

最後,我發現 belongs_to 讓 Rails 向個人模型添加了幾個實例方法,包括 getter 和 setter。它使用一種叫作元編程的高級編程技術來實現這一點。

Rails 還建立了一個 Reflection 類實例用於存儲 association 中的信息。

來自 Rails API 文檔:

Reflection 啓用了檢查 ActiveRecord 類和對象的關係和聚合的功能。例如,這種功能能夠在 form builder 中使用,該 builder 接受一個 Active Record 對象而後根據其類型爲全部屬性建立輸入字段,並顯示它與其餘對象的關聯。

挺簡潔的。

總結

雖然我不能保證解析別人的代碼會頗有意思,但這是值得的。它會給你的技術棧添加一項關鍵的技能,讓你更加自由。你將不會再依賴於完整的文檔和示例,雖然文檔很棒,但它並非萬能的。正如 Jeff Atwood 說的:

你可能能夠找到最好的,最權威和最新的文檔,可是不管文檔說什麼,源代碼纔是最真實的。

因此快去練習這項技能吧!

我相信你如今確定有一些你一直都想了解的東西。不要糾結於代碼庫的大小。打開你最喜歡的框架的倉庫而後開始學習。若是你按照我在文章中的步驟來,你很快就能成爲一名源碼專家。

若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索