本文对ruby动态方法特性进行探讨。
?
#dynamic methods class Dynamic def a puts "this is method a" end def b(bob) puts "this is method b:#{bob}" end def c puts "this is method c" end def self.define_component(name) define_method(name) do puts "my name is #{name}" end end define_component :computer define_component :car def method_missing(name,*args) methodname=name.to_s super if !%w[andy sky fly].include? methodname puts "mehtod name is:#{name}. args:#{args}" end end d=Dynamic.new d.a d.send(:b,"bob") d.send("c") d.car() d.computer() d.fly("in the sky") d.bob()
?运行结果:
?
解释:
d.send(:b,"bob") #调用对象d的方法b,参数是“bob” d.send("c") #调用对象d的方法c。? send可以理解为向对象传递一个消息,消息是调用方法。是直接调用方法的另外一种方式。 优势是方法名字可以作为变量的方式传递进来,增加了很大的灵活性,如基于这个可以把方法调用组合定义到配置文件,根据配置文件里的定义调用方法。机制有点类似java的反射。
d.car() #调用方法car d.computer()#调用方法computer
def self.define_component(name) define_method(name) do puts "my name is #{name}" end end define_component :computer #定义方法computer define_component :car #定义方法car? 3.幽灵方法和method_missing方法 幽灵方法:一个在类中没有定义的方法,但是可以运行。 method_missing:ruby定义里,如果层层都找不到方法定义,就会调用这个方法。每个类默认都继承了method_missing,且默认的实现是打印NoSushMethodErro消息。这个机制使得幽灵方法得以实现。
def method_missing(name,*args) methodname=name.to_s super if !%w[andy sky fly].include? methodname ###如果方法名不在 and sky fly里面就调用继承父方法,在这里的才继续执行。 puts "mehtod name is:#{name}. args:#{args}" end?
总结:
从动态方法的这个几个特性来看,ruby 方法定义确实是非常灵活的,也是动态语言的一大特性和优势。而在java这种静态语言里似乎很难有这种灵活性。
静态使得方法很规范,且不容易犯错(在编译期就会检查出很多错误,不会带到运行期)
动态增加了很大的灵活性,但也可能带来不规范,容易犯错,错误不好定位等问题。
各有优势,适用不同场景。