gpt4 book ai didi

Ruby 元编程 : How can make module method see class's variable

转载 作者:数据小太阳 更新时间:2023-10-29 07:24:26 25 4
gpt4 key购买 nike

例如我有一个模块和一个类:

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

我遇到异常:

uninitialized class variable @@name in SimpleModule (NameError)

我知道这里是因为模块范围与类范围不同。所以我的问题是:如何为 SimpleModule 范围共享 SimpleClass 范围?

我放元编程是因为这里只是一个简单的例子,之后我将通过从动态类调用动态模块来推进。 (这就是为什么我不想使用某些关键字,例如 includeextend 的原因)

@编辑事实上,我想自己实现 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

最佳答案

更新的答案

这是您的代码的略微修改版本。不需要 includeextendappend_featuresmodule_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

但你不想要它。 (为什么?)

你的方式

在您的代码中,SimpleClassSimpleModule 彼此完全独立。很明显,您收到了 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

使用类参数:

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

使用绑定(bind)参数:

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 SimpleClassSimpleModule 是链接的。当在 SimpleModule 中找不到方法或变量时,可以在 SimpleClass 中查找。

关于Ruby 元编程 : How can make module method see class's variable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42039474/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com