The example explains the Hook method in Ruby and adds a hook to the method call. The example explains ruby.
The Hook method is similar to the event-driven device. You can execute a specific callback function after a specific event occurs. This callback function is the hook method (more vividly described: The Hook method can be like a hook, hook up a specific event .), In Rails, The before \ after function is the most common Hook method.
The Class # inherited method is also such a hook method. When a Class is inherited, Ruby will call this method. By default, Class # inherited does not do anything. However, through inheritance, we can intercept this event and respond to the inherited event that we are interested in.
class String def self.inherited(subclass) puts “#{self} was inherited by #{subclass}” endendclass MyString < String; end
Output:
String was inherited by MyString
By using the Hook method, we can intervene in the life cycle of Ruby classes or modules, greatly improving programming flexibility.
Instance for adding a hook to a method call
Ruby has many useful hooks, such as included, inhered, and method_missing. Adding a hook to a method call can be implemented using the alias surround alias, but it is still a little troublesome. It is also troublesome to define the with_feature method in alias_method_chain. Therefore, the following module is implemented, and method_callback: before_method is called after include ,: after_method can be used to add the after_method hook for before_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 endendclass 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}"}endStudent.new.enter_class "1" do |x| puts "from lambda #{x}"end
The running result is as follows:
#enter class 1#from lambda before#after enter class doubi#from lambda after#from third enter