为什么我必须包含一个扩展来访问其模块的方法?

m0t*_*ive 1 ruby

我已经创建了一个ruby C扩展TestExt,成功编译了它,但是当我尝试在irb中使用它时,我只能在调用之后访问它的方法include TestExt.

我正在测试它:

c:/test>irb -I lib
irb(main):001:0> require 'TestExt'
=> true
irb(main):002:0> TestExt.hello()
NoMethodError: undefined method `hello' for TestExt:Module
        from (irb):2
        from C:/Ruby192/bin/irb:12:in `<main>'
irb(main):003:0> TestExt.instance_methods
=> [:hello]
irb(main):004:0> include TestExt
=> Object
irb(main):005:0> TestExt.hello()
=> 0
irb(main):006:0> hello()
=> 0
Run Code Online (Sandbox Code Playgroud)

你总是需要include延期吗?是否有一种替代的包含方式不会使方法成为hello全局?为什么我可以helloTestExt.instance_methods但不能访问它?

Jör*_*tag 5

正如你在问题中所说的那样,hello是一个实例方法,首先你需要将你的模块混合成某个东西,这样你就有了一个实例来调用它.

当你include在顶级混音时,这基本上相当于

class Object
  include TestExt
end
Run Code Online (Sandbox Code Playgroud)

其混合TestExtObject,并且因此使得hello可作为实例方法Object的类.由于所有内容都继承自Object(包括)Module,因此hello实例方法可用于TestExt模块和匿名main对象(这是self在顶层评估的内容).

尝试''.hello,它也将工作,因为你混合TestExtObjectString来自继承Object.

你总是要加一个扩展吗?

没有.

是否有另一种包含方法不会使方法hello全局?

是的:只是不要include在全球范围内.

为什么我可以在TestExt.instance_methods中看到你好但不能访问它?

因为它是一个实例方法.