在閱讀開源的 Ruby 代碼和編寫可維護(hù)性的代碼經(jīng)常遇到這兩者的使用,那么他們兩者的共同點(diǎn)和區(qū)別是什么呢?
module_function
Ruby 的 module 是 method 和 constants 的集合。module 中的method 又可分為 instance method 和 module method, 當(dāng)一個(gè) module 被 include 進(jìn)一個(gè) class ,那么 module 中的 method (注:沒有被 module_function 標(biāo)記的 method)就是 class 中的 instance method, instance method 需要所在的 class 被實(shí)例化之后才能被調(diào)用;被 module_function 標(biāo)記的 method(不管該 method 是 public 或者 private)就是 module method 且 instance method 也會(huì)變成 private method,對(duì)于被 include 所在的 class 來說是 private method,object.module_name 會(huì)出錯(cuò)。module method 都能被 module_name.method_name 調(diào)用,沒有被 module_function 標(biāo)記的 public method 不能被 module_name.method_name 調(diào)用。
module 中的 module_function 會(huì)把 module 中的 method 變成 module method 且對(duì)于被 include 所在的 class 來說,module method 在 module 中是 private method 故 module_name.module_method 能調(diào)用,而不能被 object.module_name 調(diào)用。
module 中的 public method 對(duì)于被 include 所在的 class 來說是 instance method,故 object.public_method_in_module 能調(diào)用。如果想要非 module method 能夠被 module 調(diào)用(module_name.not_module_method) ,需要引入 extend self (下文會(huì)討論 extend self)
# test.rbmodule MyModule def public_meth p "a public method, if the module is included to a class , can be call as object.public_meth" end def module_method p "a module method,can be called as module_name.module_method. but can not be call as object.module_method" end private def private_method_to_module_function p "a private_method, but can be call as module_name.module_method, because it was assigned to module_function" end def private_method p "I am a private method" end module_function :module_method, :private_method_to_module_functionendMyModule.module_methodMyModule.private_method_to_module_functionbegin MyModule.public_methrescue p "public method can not be called by module_name.public_meth"endbegin MyModule.private_methodrescue NoMethodError p "private method can not be called by module_name.module_method"endclass MyClass include MyModuleendobj = MyClass.newobj.public_methbegin obj.private_methodrescue NoMethodError p "private method in module can not be call by object.method_name"endbegin obj.module_methodrescue NoMethodError p "module method can not be called by object.method_name, for object, module method is private instance method"end#調(diào)用ruby test.rb"a module method,can be called as module_name.module_method. but can not be call as object.module_method""a private_method, but can be call as module_name.module_method, because it was assigned to module_function""public method can not be called by module_name.public_meth""private method can not be called by module_name.module_method""a public method, if the module is included to a class , can be call as object.public_meth""private method in module can not be call by object.method_name""module method can not be called by object.method_name, for object, module method is private instance method"
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注