鉤子方法有些類似事件驅(qū)動裝置,可以在特定的事件發(fā)生后執(zhí)行特定的回調(diào)函數(shù),這個回調(diào)函數(shù)就是鉤子方法(更形象的描述: 鉤子方法可以像鉤子一樣,勾住一個特定的事件。),在Rails中before\after函數(shù)就是最常見的鉤子方法。
Class#inherited方法也是這樣一個鉤子方法,當一個類被繼承時,Ruby會調(diào)用該方法。默認情況下,Class#inherited什么都不做,但是通過繼承,我們可以攔截該事件,對感興趣的繼承事件作出回應(yīng)。
class String def self.inherited(subclass) puts “#{self} was inherited by #{subclass}” end end class MyString String; end輸出:
String was inherited by MyString
通過使用鉤子方法,可以讓我們在Ruby的類或模塊的生命周期中進行干預(yù),可以極大的提高編程的靈活性。
對方法調(diào)用添加鉤子的實例
ruby有很多有用的鉤子,如included,inhered,以及method_missing。對方法調(diào)用添加鉤子可以用alias環(huán)繞別名實現(xiàn),但終歸有些麻煩,alias_method_chain需要定義with_feature方法也較麻煩,因此實現(xiàn)了下列module,include后調(diào)用method_callback :before_method,:after_method即可為before_method添加after_method鉤子
module AfterCall def self.included(base) base.extend(ClassMethods) end module ClassMethods def after_call when_call,then_call,*args_then,block_then alias_method "old_#{when_call}",when_call define_method when_call do |*args_when,block_when| send "old_#{when_call}",*args_when,block_when send then_call,*args_then,block_then end end end end class Student include AfterCall def enter_class sb puts "enter class #{sb}" yield('before') if block_given? end private def after_enter_class pop puts "after enter class #{pop}" yield('after') if block_given? end protected def third_after puts "from third enter" end after_call :after_enter_class ,:third_after after_call :enter_class ,:after_enter_class,"doubi", lambda {|x|puts "from lambda #{x}"} end Student.new.enter_class "1" do |x| puts "from lambda #{x}" end
運行結(jié)果如下:
#enter class 1 #from lambda before #after enter class doubi #from lambda after #from third enter