루비의 모듈_function 과 extendself 는 동일하다

5520 단어 rubyextendself
오픈소스인 루비 코드를 읽고 유지보수 가능한 코드를 작성하는 데 자주 부딪힌다. 그렇다면 이들의 공통점과 차이점은 무엇일까?
module_function
루비의 모듈은 method와 constants의 집합입니다.모듈의 method는 instance method와module method로 나눌 수 있습니다. 모듈이 include에 의해 class에 들어가면 모듈의 method(주:module_function에 표시되지 않은 method)는class의 instance method입니다. instance method는 있는 class가 실례화되어야 호출됩니다.모듈에 의해_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 호출.
모듈의 모듈_function은module의method를modulemethod로 변환하고include가 있는class에modulemethod는module에서privatemethod이기 때문에module_name.module_method는object에 호출되지 않습니다.module_name 호출.
모듈의public method는include가 있는class에 대해instance method이기 때문에object입니다.public_method_in_모듈은 호출할 수 있습니다.모듈이 아닌 method가 모듈에 호출될 수 있도록 하려면 (module_name.not_module_method) extendself를 도입해야 합니다.

# test.rb
module 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_function
end

MyModule.module_method
MyModule.private_method_to_module_function
begin
 MyModule.public_meth
rescue
 p "public method can not be called by module_name.public_meth"
end
begin
 MyModule.private_method
rescue NoMethodError
 p "private method can not be called by module_name.module_method"
end

class MyClass
 include MyModule
end

obj = MyClass.new
obj.public_meth

begin
 obj.private_method
rescue NoMethodError
 p "private method in module can not be call by object.method_name"
end

begin
 obj.module_method
rescue 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"

총결산은 바로
•The method will be copied to class' singleton class
•The instance method's visibility will become private
extend self
Include is for adding methods to an instance of a class and extend is for adding class methods
extend 본질은class나module에classmethod를 추가하는 것이다
extendself는module의instance method를module_name.instance_method 호출,module에서 원래 method의public나private 속성을 보존하지만module_function처럼 표시된method를private로 만듭니다.

#!/usr/bin/env ruby
# encoding: utf-8
# test_extend.rb
module MyModule
 extend self
 def public_meth
  p "a public_method extended by self can be called by module_name.public_meth and object.public_meth, included by a class"
  private_method
 end
 private
 def private_method
  p "a private method, can be call in module internal"
 end
end

class MyClass
 include MyModule
end

MyModule.public_meth

begin
 MyModule.private_method
rescue NoMethodError
 p "private method in extend self module can not be called module_name.private_method"
end

obj = MyClass.new
obj.public_meth

begin
 obj.private_method
rescue NoMethodError
 p "private method can not be called by object.private_method"
end

#   ruby test_extend.rb
"a public_method extended by self can be called by module_name.public_meth and object.public_meth, included by a class"
"a private method, can be call in module internal"
"private method in extend self module can not be called module_name.private_method"
"a public_method extended by self can be called by module_name.public_meth and object.public_meth, included by a class"
"a private method, can be call in module internal"
"private method can not be called by object.private_method"

요약:
•No method copying involved
•No changes to method visibility
총결산
module_function 모듈 내 원래 method의public/private 속성을 바꾸고 method를module method로 바꾸면 모듈_name.module_method 호출.
extendself는 모듈에서 계승하는 것입니다. 모듈에서 method의public/private 속성을 바꾸지 않고module_name.public_method

좋은 웹페이지 즐겨찾기