可以利用Module#define_method( )方法定义一个方法,只需要为其提供一个方法名和一个充当方法主体的块即可。
例1: define_method方法在MyClass内部执行,所以add方法定义为MyClass的实例方法。
- class MyClass
- define_method :add do |args|
- args * 3
- end
- end
- obj = MyClass.new
- result = obj.send(:add,3)
- puts result #=>9
- class MyClass
- def self.new_method(name, &block)
- define_method(name, &block)
- puts block.inspect
- end
- end
- MyClass.new_method(:show) { puts "show" }
- c = MyClass.new
- c.show
- c.send(:show)
method_missing方法。
- class MyOpenStruct
- def initialize
- @attr = {}
- end
- def method_missing(name,*args)
- puts "you called: #{name}"
- attr = name.to_s
- if attr =~ /=$/
- @attr[attr.chop] = args[0]
- else
- @attr[attr]
- end
- end
- end
- i = MyOpenStruct.new
- i.flavor = "hello" #先调用flavor=方法
- puts i.flavor #=> hello 后调用flavor方法
- class Roulette
- def method_missing(name,*args)
- person = name.to_s.capitalize
- num = 0
- 3.times do
- num = rand(10)+1
- puts "#{num}...."
- end
- "#{person} get a #{num} "
- end
- end
- obj = Roulette.new
- puts obj.bob
- puts obj.frank
ruby的作用域
- v1 = 1
- class MyClass
- v2 = 2
- puts local_variables
- def my_method
- v3 = 3
- puts local_variables
- end
- puts local_variables
- end
- obj = MyClass.new
- obj.my_method
- obj.my_method
- puts local_variables
- #输出:v2 v2 v3 v3 v1 obj
考虑下面一个问题?
怎样让一个变量穿过不同的作用域?
- my_var = "success"
- class MyClass
- #希望在这里显示my_var
- def my_method
- #希望在这里显示my_var
- end
- end
实现方法:扁平作用域。如果使用方法来替代作用域的门,那么可以让一个作用域看到另一个作用域中的变量。
- var = "success"
- MyClass = Class.new do
- puts "#{var} in class definition!"
- define_method :my_method do
- puts "#{var} in method"
- end
- end
- obj = MyClass.new
- obj.my_method
共享作用域
- def my_method
- shared = 0
- Kernel.send :define_method, :counter do
- shared
- end
- Kernel.send :define_method, :inc do |x|
- shared += x
- end
- end
- my_method
- puts counter
- inc(4)
- puts counter