例如,我有一个模块和一个类:
module SimpleModule
def self.class_hello
puts "hello from #{@@name}"
end
end
class SimpleClass
@@name = 'StackOverFlow'
def self.test
SimpleModule.class_hello
end
end
然后我通过从类中调用模块方法进行测试:
SimpleClass.test
我遇到异常(exception):
我在这里知道是因为模块的作用域与类的作用域不同。所以我的问题是:如何为SimpleModule范围共享SimpleClass范围?
我之所以使用元编程,是因为这只是一个简单的示例,此后,我将通过从动态类调用动态模块来进行高级处理。 (这就是为什么我不想使用诸如 include 或extend 之类的关键字的原因)
@编辑
实际上,我想自己实现Ruby扩展。这是我已经开发的版本:
# implementation
class Class
def custom_extend(module_name)
module_name.methods(false).each do |method|
define_singleton_method(method) do |*args, &block|
module_name.send(method, *args, &block)
end
end
end
end
这是我的自定义模块和测试类:
# -------------------------------------------------------------
# Demonstration
module SimpleModule
def self.class_hello_world
puts 'i am a simple module boss'
end
def self.class_hello_name
puts "hello from #{@@name}"
end
end
class SimpleClass
custom_extend SimpleModule
@@name = 'StackOverFlow'
end
这是我的两个测试:
SimpleClass.class_hello_world # work
SimpleClass.class_hello_name # not work
最佳答案
更新的答案
这是您的代码的稍作修改的版本。不需要include
,extend
,append_features
或module_function
。添加具有相同结构的custom_include
并不难。
更新:确保阅读@ 7stud的answer,具有类似的结构和很好的说明。
class Class
def custom_extend(module_name)
module_name.instance_methods(false).each do |method|
define_singleton_method(method) do |*args, &block|
module_name.instance_method(method).bind(self).call(*args, &block)
end
end
end
end
module SimpleModule
def class_hello
puts "hello from #{@name}"
end
end
class SimpleClass
@name = 'class'
custom_extend SimpleModule
def self.test
class_hello
end
end
SimpleClass.test
#=> hello from class
原始答案
平常的方式
通常的方式是:
module SimpleModule
def class_hello
puts "hello from #{@name}"
end
end
class SimpleClass
@name = 'StackOverFlow'
extend SimpleModule
def self.test
class_hello
end
end
SimpleClass.class_hello
但是你不想要它。 (为什么?)
你的方式
在您的代码中,
SimpleClass
和SimpleModule
彼此完全独立。很明显,您得到了NameError
。您需要以某种方式传递name
信息。作为名称参数:
module SimpleModule
def self.class_hello(name='')
puts "hello from #{name}"
end
end
class SimpleClass
@@name = 'StackOverFlow'
def self.test
SimpleModule.class_hello(@@name)
end
end
使用klass参数:
module SimpleModule
def self.class_hello(calling_class=self)
calling_class.class_eval{
puts "hello from #{@name}"
}
end
end
class SimpleClass
@name = 'StackOverFlow'
def self.test
SimpleModule.class_hello(self)
end
end
SimpleClass.test
使用
binding
参数:module SimpleModule
def self.class_hello(b)
puts "hello from #{b.eval('@@name')}"
end
end
class SimpleClass
@@name = 'StackOverFlow'
def self.test
SimpleModule.class_hello(binding)
end
end
SimpleClass.test
用
my_ruby_extend SimpleModule
当然可以使用自定义
my_ruby_extend
来完成。但是,您需要显示所需的语法以及已经实现的内容。这样,您可以告诉Ruby
SimpleClass
和SimpleModule
是链接的。如果在SimpleModule
中找不到方法或变量,则可以在SimpleClass
中进行查找。