在閱讀開源的 Ruby 代碼和編寫可維護性的代碼經常遇到這兩者的使用,那么他們兩者的共同點和區別是什么呢?
module_function
Ruby 的 module 是 method 和 constants 的集合。module 中的method 又可分為 instance method 和 module method, 當一個 module 被 include 進一個 class ,那么 module 中的 method (注:沒有被 module_function 標記的 method)就是 class 中的 instance method, instance method 需要所在的 class 被實例化之后才能被調用;被 module_function 標記的 method(不管該 method 是 public 或者 private)就是 module method 且 instance method 也會變成 private method,對于被 include 所在的 class 來說是 private method,object.module_name 會出錯。module method 都能被 module_name.method_name 調用,沒有被 module_function 標記的 public method 不能被 module_name.method_name 調用。
module 中的 module_function 會把 module 中的 method 變成 module method 且對于被 include 所在的 class 來說,module method 在 module 中是 private method 故 module_name.module_method 能調用,而不能被 object.module_name 調用。
module 中的 public method 對于被 include 所在的 class 來說是 instance method,故 object.public_method_in_module 能調用。如果想要非 module method 能夠被 module 調用(module_name.not_module_method) ,需要引入 extend self (下文會討論 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#調用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"
新聞熱點
疑難解答