我會盡量解釋它一點點更深:
當你include
模塊插入一些類,紅寶石,創建特殊的內部包括類,並將其添加到層次結構(請注意,基本上你是不允許看包括類從紅寶石PROGRAMM,它是隱藏類):
Given A inherits B
And we have a module C
When A includes C
Then A inherits includeC inherits B
如果包括模塊具有其他包含的模塊,然後includeModules將這些模塊以及創建:
Given A inherits B
And we have a module C
And C includes module D
When A includes C
Then A inherits includeC inherits includeD inherits B
包括類 C法表是一個鏈路到原始類C的方法表
當extend
一些對象,具有一個模塊,則該模塊被納入單例類這個對象,因而:
class << self; include C; end
# is the same as
extend C
去你的例子:
module Kernel
extend Talk
end
在這裏包括Talk
模塊插入的單個類的Kernel
(Kernel
是Module
類的一個對象)。這就是爲什麼您只能在內核對象Kernel.hello
上調用hello
方法的原因。
如果我們寫:
module Kernel
include Talk
end
然後Kernel
將在內部繼承包括類 includeTalk(類鏈接Talk
方法)。
但已經包含內核模塊爲Object
- Object
繼承自己的includeKernel類includeKernel類有鏈接的Kernel
方法表,並沒有看到法新包括Kernel
類。
但如果你現在將重新加入內核爲對象,所有對象都會看到方法講座的:
> module Talk
> def hi
> puts 'hi'
> end
> end
=> nil
> module Kernel
> include Talk
> end
=> Kernel
> hi
NameError: undefined local variable or method `hi` for main:Object
from (irb):9
from /usr/share/ruby-rvm/rubies/ruby-1.9.2-p290/bin/irb:16:in `<main>`
> class Object
> include Kernel
> end
=> Object
> hi
hi
=> nil
probjem可能是你的解決方案來擴展主要對象與您的新模塊:
extend Talk
希望這澄清了一點問題,您觀察:)
UPDATE
將試圖澄清你的問題:
我還是有點困惑,爲什麼我要重新包括內核的對象。在 不涉及主要對象的情況下,我可以基於類實例化對象 ,然後重新打開該類幷包含 模塊,該對象將在我的模塊中看到方法。有沒有 關於主對象如何包含內核的東西有所不同?我是 也不知道你的意思是「對象繼承自己的includeKernel 類和includeKernel類......」爲什麼它看不到內核中包含的新模塊 ?
您講述與直接包含模塊到類對象的情況下:
module M
def hi
puts 'hi'
end
end
class C
end
c = C.new
c.hi # => UndefinedMethod
class C
include M
end
c.hi # => hi
在這種情況下,你將有C
類的對象c
。類C
繼承Object
(因爲它是一個實例的Class
類。c在他的單例類 - >然後在他的類C - >然後在類C的父類(在這種情況下爲Object
實例方法)中查找其實例方法。當我們包括模塊M
爲C
類,那麼includeM
將是C
超類,如果c
在他的單例類和C
類不會找到他的實例方法,它會在includeM
實例方法搜索。includeM
有一個鏈接方法表M
類(Module
類的實例)。因此,當c
搜索實例方法hi
它發現它在第e M
模塊。
但這與將模塊M
納入Kernel
模塊的情況不同。 在程序開始Object
類包括模塊Kernel
:class Object; include Kernel; end
。這就是爲什麼我說Object
繼承自includeKernel
。 includeKernel
有鏈接的Kernel
方法表,當你改變內核的方法表,includeKernel
也將看到這些變化:
module Kernel
def hi # add hi method to method table of Kernel
puts 'hi'
end
end
hi # => hi # any Object now see method hi
但是當你有模M進入內核,那麼方法內核的表沒有改變。相反,Kernel現在將繼承includeM
,包括類。includeKernel
由於不知道Kernel
和includeM
的繼承鏈,因此只知道Kernel
的方法表。
但是,當你重新加入到Kernel
Object
,包含機制將看到Kernel
包括M
併爲Object
創建includeM爲好。現在Object
將繼承includeKernel
將繼承includeM
將繼承BasicObject
。
傑克@AlexKliuchnikau釘了它;請接受他的回答!並查看他發佈了鏈接的「Ruby黑客指南」! – 2012-02-14 09:05:13