19e786a2a74377ff6e052d87fd8d1fa8

[重大修改] Rails 3.2 拿掉了 ActiveSupport::Concern 的 InstanceMethods

2012-01-03 16:31:27 +0800xditeRuby on Rails 節點 中發起
最後由 scriptfans2012-01-11 10:13:19 +0800回應 , 1321次閱讀

今天把線上的 production 掛上 Rails 3.2 pre 玩一下。結果跳出這一段

DEPRECATION WARNING: The InstanceMethods module inside ActiveSupport::Concern will be no longer included automatically. Please define instance methods directly in ActionController::Base instead.

而且不少地方被影響到。

翻了一下,才發現因為 Jose Valim 認為當初 AS::Concern 這樣的寫法影響了不少人,而且是個"爛" pattern。於是計畫移除,在 3.2 丟出 warning...

Git Commit:
http://github.com/rails/rails/commit/401393b6561adc1ce7101945163c9601257c057a

具體討論:

http://patshaughnessy.net/2011/12/6/learning-from-the-masters-some-of-my-favorite-rails-commits

舉例來說,原先大家通常會這樣包裝 module 的:

module M
  extend ActiveSupport::Concern

  module ClassMethods

    ...

  end

  module InstanceMethods
    ...
  end

end

Valim 希望大家以後在使用 AS::Concern 時這樣寫

module M
  extend ActiveSupport::Concern

  module ClassMethods

    ...

  end

  def abc
     xyz
  end

end

他希望以後大家直接 define instance method。不要再包一層 include InstanceMethods 脫褲子放屁...

別誤會,當然你想要繼續以這種形式包裝 Method 還是可以..

module M
  def self.included(base)
    base.extend ClassMethods
    base.send(:include, InstanceMethods)
    scope :disabled, where(:disabled => true)
  end

  module ClassMethods

    ...

  end

  module InstanceMethods
    ...
  end

end

只是若你之後要使用 extend AS::Concern 自動掛 ClassMethods / InstanceMethods 這招時。AS::Concern 不會「自動」幫你掛上去 InstanceMethods。

這個影響非常巨大,因為自從 AS::Concern 誕生以來,已經不少人習慣這樣整理程式碼,並 extend AS::Concern。估計不少 gem 要做出修改...

截至 2012-01-11 10:13:19 +0800,共收到 2 條回應
Ea44bd120ed7cf301d561bcc3e7a6c96
blackanger 1樓, 於2012-01-06 10:24:58 +0800回應

我比较认同Jose Valim的看法。

1fe2e02a9933fa4f20adaf8ce2488d5d
scriptfans 2樓, 於2012-01-11 10:13:19 +0800回應

nod
以前的写法就是浪费精神,本来include就会把instance method加入进去的。

需要 登入 後方可回應,如果你還沒有帳號按這裡 註冊