gpt4 book ai didi

Ruby 元编程 : cannot send a method to a module

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

例如我有以下自定义类和模块:

module SimpleModule
def hello_world
puts 'i am a SimpleModule method'
end

def self.class_hello_world
puts 'i am a SimpleModule class method'
end
end

class SimpleClass
def hello_world
puts 'i am SimpleClass method'
end

def self.class_hello_world
puts 'i am a SimpleClass class method'
end
end

我尝试使用send方法在类和模块中调用这些方法

SimpleClass.send(class_hello_world)  # work
SimpleClass.new.send(hello_world) # work
SimpleModule.send(class_hello_world) # work
SimpleModule.new.send(hello_world) # not work
SimpleModule.send(hello_world) # not work

换句话说,我不知道如何从SimpleModule 调用hello_world。如果之前用 self 定义了该方法,则有可能。

我需要这样做是因为我想实现一个“自定义包含”:包括从模块到另一个类的所有方法。

请告诉我该怎么做。

最佳答案

五个陈述

让我们一次考虑这五个陈述(但顺序与呈现的顺序不同)。请注意,send 的参数必须是以字符串或符号表示的方法名称。

SimpleModule.send("class_hello_world")
# i am a SimpleModule class method

这很正常,尽管此类方法通常称为模块方法。一些常用的内置模块,如Math , 仅包含模块方法。

SimpleClass.send(:class_hello_world)
# i am a SimpleClass class method

因为类是模块,所以行为与上面相同。 class_hello_world 通常被称为类方法

SimpleClass.new.send(:hello_world)
# i am SimpleClass method

这是实例方法的正常调用。

SimpleModule.send("hello_world")
#=> NoMethodError: undefined method `hello_world' for SimpleModule:Module

没有模块方法hello_world

SimpleModule.new.send(hello_world)
#=> NoMethodError: undefined method `new' for SimpleModule:Module

不能创建模块的实例。

includeprepend

假设有人写

SimpleClass.include SimpleModule
#=> SimpleClass
SimpleClass.new.hello_world
# i am SimpleClass method

所以 SimpleClass 的原始方法 hello_world 没有被模块的同名方法覆盖。考虑 SimpleClass 的祖先。

SimpleClass.ancestors
#=> [SimpleClass, SimpleModule, Object, Kernel, BasicObject]

在考虑 SimpleModule 之前,Ruby 会在 SimpleClass 中寻找 hello_world 并找到它。

但是,可以使用 Module#prependSimpleModule#hello_world 放在 SimpleClass#hello_world 之前。

SimpleClass.prepend SimpleModule
#=> SimpleClass
SimpleClass.new.hello_world
# i am a SimpleModule method
SimpleClass.ancestors
#=> [SimpleModule, SimpleClass, Object, Kernel, BasicObject]

绑定(bind)未绑定(bind)方法

您还要做另一件事。 SimpleModule 的实例方法(这里只有一个)是未绑定(bind)的。你可以使用 UnboundMethod#bind将每个绑定(bind)到 SimpleClass 的实例,然后使用 callsend 执行它。

sc = SimpleClass.new
#=> #<SimpleClass:0x007fcbc2046010>
um = SimpleModule.instance_method(:hello_world)
#=> #<UnboundMethod: SimpleModule#hello_world>
bm = um.bind(sc)
#=> #<Method: SimpleModule#hello_world>
bm.call
#=> i am a SimpleModule method
sc.send(:hello_world)
#=> i am a SimpleModule method

关于Ruby 元编程 : cannot send a method to a module,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42036886/

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