ruby和rails中的回调函数

Ruby中Class,Object,Module这三个类定义了一些回调方法,这些方法不是默认的不过为一个类模块获对象定义了这些方法,当特定的事件发生时,将调用这些回调和钩子方法。这些回调方法一般以"ed"结尾。特定事件是指:
调用一个不存的对象方法(method_missing)
模块被混含(included/extended)
类被继承(inherited)

类或模块定义实例方法(method_added)

对象新增加一个单例方法(singleton_method_added)

实例方法被删除或取消(method_removed/method_undefined)

对象的单例方法被取消或被取消(singleton_method_removed/singleton_undefined)
引用一个不存在的常量(const_missing)
以上每一个事件对应的方法被定义了,当事件发生时,这些方法将会被调用。

method_missing
给对象调用一个方法,对象未定义,则会抛出NoMethodError异常,这时就可以使用method_missing来拦截,该方法接受为一个一个参数,即被调用的未定义方法的方法名。
class C
def method_missing(m)
puts "There's no method called #{m} here -- please try again."
end
end
C.new.anything
这里就会调用method_missing方法。
method_missing是一个有用的工具,在所有Ruby标准的钩子方法和回调方法中,是使用最广泛的一个回调方法。

Module#included
当一个模块混入到类时,如果该模的included方法已经定义,那么该方法被调用。该方法的唯一参数就是接受混含的类的名字。
module M
def self.included(c)
puts "I have justbeen mixed into #{c}."
end
end
class C
include M
end
混含模块到类中使得在模块中的所有实例方法可以被作为类的实例的方法。如果在混含模块时要给包含此模块的类添加类方法不能采用形如:def self.method_name end形式,可以用included回调方法。
用included可以捕获混含操作,并以此给混含模块的类添加类方法:
module M
def self.included(c)
def c.a_class_method
puts "Now the class has a new class method."
end
end
end

class C
include M
end
c = C.new
C.a_class_method
输出结果:
Now the class has a new class method.
由于C做为included的唯一参数传入到c,接着定义了c.a_class_method就相当于是给类C定义了类方法,extended方法与此类似。

有的人喜欢以此种方式给模块添加实例及类方法:

module M

  self.included(recipient)

    recipient.extend(ModuleClassMethods)

    recipient.class_eval do

      include ModuleInstanceMethods

    end

  end

  module ModuleClassMethods

    #定义类方法

  end

  module ModuleInstanceMethods

    #定义实例方法

  end

end



method_added

class A

  def self.method_added(name)

    puts "#{name} is a new method"

  end

end



class A

  def a

  end

end

a is a new method

此方法接受一个参数为新定义方法的方法名,若定义了此方法,以后每次为这个类增加一个新方法时都会调用method_add方法,类似的当定义了singleton_method_added方法时为对象添加单例方法时会被调用,对于类对象来说单例方法就是类方法。


Class#inherited
如果为给定的类定义了inherited方法,那么在为它生成子类时,inherited会被调用,唯一的调用参数是新的子类的名字:
class C
def self.inherited(subclass)
puts "#{self} just got subclassed by #{subclass}"
end
end
class D < C
end
D继承C,触发了inherited方法,输出结果:
C just got subclassed by D

Module#const_missing
在给定的模块或类中引用一个不可识别的常量时,该方法被调用:
class C
def self.const_missing(const)
puts "#{const} is undefined-setting it to 1."
const_set(const, 1)
end
end
puts C::A
puts C::A
输出结果:
A is undefined-setting it to 1.
1
1

附:rails activerecord回调方法(以创建新记录为例,更新记录也类似将下列create改为update即可):

save
valid?
(1) before_validation
(2) before_validation_on_create
validate
validate_on_create
(3) after_validation
(4) after_validation_on_create
(5) before_save
(6) before_create
数据库插入
(7) after_create
(8) after_save

共8个回调方法为上述标号(1)至(8)

来源:http://consy.blog.51cto.com/2212530/399959

你可能感兴趣的:(C++,c,C#,Ruby,Rails)