可以利用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