【ruby】ruby 动态方法总结
2014-04-27 17:30
330 查看
本文对ruby动态方法特性进行探讨。
结合以下例子:
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()
运行结果:
解释:
1.send方法
Ruby代码
d.send(:b,"bob") #调用对象d的方法b,参数是“bob”
d.send("c") #调用对象d的方法c。
send可以理解为向对象传递一个消息,消息是调用方法。是直接调用方法的另外一种方式。
优势是方法名字可以作为变量的方式传递进来,增加了很大的灵活性,如基于这个可以把方法调用组合定义到配置文件,根据配置文件里的定义调用方法。机制有点类似java的反射。
2.define_method方法
define_method提供了一个强大的功能,定义方法。可以认为是元编程,编写代码的代码。假设有很多类似的方法,方法的结构基本是一样的,只是名字或参数不一样,这时候定义这样多个的方法就可以通过define_method来动态生成。
Ruby代码
d.car() #调用方法car
d.computer()#调用方法computer
虽然类Dynamic没显式定义car和computer方法,但是能调用者两个方法是因为通过define_method元编程定义了这个两个方法。如下:
##定义了一个类方法,方法的功能就是根据入参,定义方法
Ruby代码
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消息。这个机制使得幽灵方法得以实现。
以上例子:
d.fly("in the sky")能够调用通过 而d.bob()不能调用通过,正式因为Dynamic类的method_missing是这样定义的:
Ruby代码
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这种静态语言里似乎很难有这种灵活性。
静态使得方法很规范,且不容易犯错(在编译期就会检查出很多错误,不会带到运行期)
动态增加了很大的灵活性,但也可能带来不规范,容易犯错,错误不好定位等问题。
各有优势,适用不同场景。
转自:http://singleant.iteye.com/blog/1680382
结合以下例子:
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()
运行结果:
解释:
1.send方法
Ruby代码
d.send(:b,"bob") #调用对象d的方法b,参数是“bob”
d.send("c") #调用对象d的方法c。
send可以理解为向对象传递一个消息,消息是调用方法。是直接调用方法的另外一种方式。
优势是方法名字可以作为变量的方式传递进来,增加了很大的灵活性,如基于这个可以把方法调用组合定义到配置文件,根据配置文件里的定义调用方法。机制有点类似java的反射。
2.define_method方法
define_method提供了一个强大的功能,定义方法。可以认为是元编程,编写代码的代码。假设有很多类似的方法,方法的结构基本是一样的,只是名字或参数不一样,这时候定义这样多个的方法就可以通过define_method来动态生成。
Ruby代码
d.car() #调用方法car
d.computer()#调用方法computer
虽然类Dynamic没显式定义car和computer方法,但是能调用者两个方法是因为通过define_method元编程定义了这个两个方法。如下:
##定义了一个类方法,方法的功能就是根据入参,定义方法
Ruby代码
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消息。这个机制使得幽灵方法得以实现。
以上例子:
d.fly("in the sky")能够调用通过 而d.bob()不能调用通过,正式因为Dynamic类的method_missing是这样定义的:
Ruby代码
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这种静态语言里似乎很难有这种灵活性。
静态使得方法很规范,且不容易犯错(在编译期就会检查出很多错误,不会带到运行期)
动态增加了很大的灵活性,但也可能带来不规范,容易犯错,错误不好定位等问题。
各有优势,适用不同场景。
转自:http://singleant.iteye.com/blog/1680382
相关文章推荐
- Ruby中Require、Load、Include和Extend的区别
- ruby on rails 配置mysql 方法
- Ruby:Nokogiri
- RubyMine4.5.4 debug手动安装方法简介
- Ruby 一些常用的细节
- Ruby on Rails 初探 安装篇
- ruby 类变量 实例变量
- Ruby on Rails 导入CSV文件至数据库
- Ruby On Rails 导出数据库至CSV文件
- Ruby on Rails 对静态网页的处理
- ruby之父真是一个可爱的人
- Ruby学习笔记系列(二)--学习资料收集
- cucumber系列(一) RubyGems下载源更新的问题
- ruby 循环
- Ruby如何实现动态方法调用?
- Ruby学习笔记系列(三)
- Ruby学习笔记系列(一)
- Ruby:字符串处理函数
- Ruby on Rails (坑)
- Ruby 里的 include,require,load的显著区别