Monkey Patch猴子補丁編程方式及其在Ruby中的運用_ruby專題

來源:互聯網
上載者:User

何謂猴子補丁(Monkey Patch)?在動態語言中,不修改原始碼而對功能進行追加和變更。

使用猴子補丁的目的:
1、追加功能
2、功能變更
3、修正程式錯誤
4、增加鉤子,在執行某個方法的同時執行一些其他的處理,如列印日誌,實現AOP等,
5、緩衝,在計算量很大,結算之後的結果可以反覆使用的情況下,在一次計算完成之後,對方法進行替換可以提高處理速度。

Ruby的類都是開放類,即在類定義之後還可以任意新增內容, 這就使得在Ruby中使用猴子補丁變得特別容易了。另外,Ruby還提供了對方法、類和模組的進行操作的功能,讓我們使用猴子補丁更加得心應手。Ruby提供的準系統如下:
      alias:給方法另起別名
      include:引入其他模組的方法
      remove_method: 取消本類中的方法
      undef:取消方法 
     
在 Ruby 中使用 Monkey Patch
我當時遇到的情境是這樣的:

我司使用第三方庫 fog 進行 EC2 的操作。建立執行個體等很多命令都需要設定執行個體類型這個參數。在 fog 裡,EC2 的所有類型都定義在 fog/aws/models/compute/flavors.rb 的 FLAVORS 數組裡。如果設定的類型不在 FLAVORS 數組裡,fog 都會視作是無效的參數而報錯。

後來,亞馬遜發布了新的執行個體類型 D2。雖然 Ruby 的第三方社區非常活躍,但是 fog 的開發社區還是沒有及時添加 D2 到 flavors.rb 裡;而我司的工作又迫切需要使用 D2 類型的執行個體。

背景交待完畢,接下來看看有什麼樣的解決方案。

方法一:我們可以向 fog 提交一個 Pull Request 來添加新類型。

但是這個方法行不通。我們使用的 knife-ec2 對 fog 的版本依賴必須是 1.25.*,但是 fog 已經更新到了 1.31.0,而且 fog 從 1.27.0 開始結構上有很大的變化。顯然,我們不可能再等 knife-ec2 升級支援新版本的 fog,所以我們提交 Pull Request 更新 fog 不能解決問題。

方法二:手動更新舊版 fog 既然不能使用最新版的 fog,我們可以手動編輯 1.25 版的 fog,再打包成 Gem 使用。這個方法比前一個方法更容易操作,但是帶來的問題時不易於維護。為了一個極小的改動,把自己的代碼加入到第三方庫中總是讓人覺得不夠「乾淨」。

最後,在同事的指點下,我採用了第三種方法,即 Monkey Patch。我在我司的 Ruby 項目裡添加了一個檔案 lib/PROJECT_NAME/monkey_patches/flavors.rb,接著在檔案中添加以下代碼來修改 fog/aws/models/compute/flavors:

require 'fog/aws/models/compute/flavors'class Object def redef_without_warning(const, value)  mod = self.is_a?(Module) ? self : self.class  mod.send(:remove_const, const) if mod.const_defined?(const)  mod.const_set(const, value) endendmodule Fog module Compute  class AWS   NEW_FLAVORS = FLAVORS + [    {     :id => "d2.xlarge",     ...    },    {     :id => "d2.2xlarge",     ...    },    {     :id => "d2.4xlarge",     ...    },    {     :id => "d2.8xlarge",     ...    }   ]   redef_without_warning :FLAVORS, NEW_FLAVORS  end endend

總結
通過在自己的代碼中添加一個 Monkey patch,我們成功地實現了向 fog 中動態添加新執行個體類型。我司終於可以使用 fog 建立 D2 類型的機器了;而且這個方法改動的代碼量最小,也更加容易維護。

Monkey Patch 並非是完美的解決方案,它會引入一些陷阱。所以這個技巧在軟體工程領域還有一些爭議。不過,我還是覺得 Monkey Patch 是一個不錯的零時性解決方案。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.