五個陳述
讓我們看看這五個語句一次一個(但以不同的順序不是提交)。請注意,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
無法創建模塊的實例。
include
VS prepend
假設一書中寫道
SimpleClass.include SimpleModule
#=> SimpleClass
SimpleClass.new.hello_world
# i am SimpleClass method
所以SimpleClass
「原來的方法hello_world
沒有同名由模塊的方法覆蓋。考慮SimpleClass
的祖先。
SimpleClass.ancestors
#=> [SimpleClass, SimpleModule, Object, Kernel, BasicObject]
紅寶石會尋找hello_world
在SimpleClass
--and找到它 - 考慮SimpleModule
之前。
但是,可以使用Module#prepend將SimpleModule#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]
綁定綁定方法
有你做一兩件事。 SimpleModule
的實例方法(這裏只有一個)沒有綁定。您可以使用UnboundMethod#bind將每個綁定到SimpleClass
的實例,然後使用call
或send
執行。
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
'SimpleModule.new.send(hello_world)'不起作用,因爲您不能擁有模塊的實例。 –
@EddeAlmeida謝謝。所以Ruby通過其語言實現關鍵字「包含」,或者我可以使用元編程來做類似的事情?如果元編程可能的話,應該有一個來自模塊的調用方法。 –