我正在研究ruby中面向上下文的编程项目。我遇到了这个问题:
假设我有一个Klass类:
class Klass
def my_method
proceed
end
end
我还在变量impl
中存储了一个proc。 impl
包含{ puts "it works!" }
。
从Klass以外的某个地方,我想在方法proceed
中定义一个名为my_method
的方法。因此,如果调用Klass.new.my_method
,我会得到结果"it works"
。
所以最后的结果应该是这样的:
class Klass
def my_method
def proceed
puts "it works!"
end
proceed
end
end
或者如果您有任何其他想法让proceed
my_method
内的proceed
调用,那也很好。但是另一种方法my_method_2
(比方说my_method
)与proceed
不同。
实际上,my_method
的{{1}}代表my_method
的旧版本。 proceed
的{{1}}代表my_method_2
的旧版本。
感谢您的帮助
答案 0 :(得分:1)
免责声明: 你做错了!
必须更健壮,优雅和红宝石的方式来实现你想要的。如果您仍想滥用元编程,请转到:
class Klass
def self.proceeds
@proceeds ||= {}
end
def def_proceed
self.class.proceeds[caller.first[/`.*?'/]] = Proc.new
end
def proceed *args
self.class.proceeds[caller.first[/`.*?'/]].(*args)
end
def m_1
def_proceed { puts 1 }
proceed
end
def m_2
def_proceed { puts 2 }
proceed
end
end
inst = Klass.new
inst.m_1
#⇒ 1
inst.m_2
#⇒ 2
您实际需要的是Module#prepend
并从那里致电super
。
答案 1 :(得分:0)
这样做的一种方法是构造一个哈希,其键是调用proceed
的方法的名称,其值是proc,表示调用它的每个方法的proceed
的实现。
class Klass
singleton_class.send(:attr_reader, :proceeds)
@proceeds = {}
def my_method1(*args)
proceed(__method__,*args)
end
def my_method2(*args)
proceed(__method__,*args)
end
def proceed(m, *args)
self.class.proceeds[m].call(*args)
end
end
def define_proceed(m, &block)
Klass.proceeds[m] = Proc.new &block
end
define_proceed(:my_method1) { |*arr| arr.sum }
define_proceed(:my_method2) { |a,b| "%s-%s" % [a,b] }
k = Klass.new
k.my_method1(1,2,3) #=> 6
k.my_method2("cat", "dog") #=> "cat-dog"