Ruby의 비공개 모듈 메소드
두 부분으로 된 질문이 있습니다.
모범 사례
- 공용 인터페이스를 사용하여 데이터 구조에서 일부 작업을 수행하는 알고리즘이 있습니다.
- 현재 하나의 공용 인터페이스 메소드를 제외하고 모두 전용 인 수많은 정적 메소드가있는 모듈입니다.
- 모든 메소드간에 공유해야하는 인스턴스 변수가 하나 있습니다.
다음은 내가 볼 수있는 옵션이며 가장 좋은 것은 무엇입니까? :
- 모듈 정적 (루비 '모듈')와 방법
- 정적 메서드가있는 클래스
- 데이터 구조에 포함하기위한 Mixin 모듈
- 해당 데이터 구조 (매우 작음)를 수정하는 알고리즘 부분을 리팩터링 하고 알고리즘 모듈의 정적 메소드를 호출하는 믹스 인으로 만듭니다.
기술 부분
private Module 방법을 만드는 방법이 있습니까?
module Thing
def self.pub; puts "Public method"; end
private
def self.priv; puts "Private method"; end
end
private거기에는 어떤 영향을 미칠 것 같지 문제 난 여전히 호출 할 수 있습니다 Thing.priv.
나는 모든 것이되는 편리한 다루는 모듈 내에서 클래스를 만드는 것이 최선의 방법 (그리고 대부분의 기존 라이브러리가 작성 방법)이라고 생각하며, 모듈은 단지 방법을 제공합니다.
module GTranslate
class Translator
def perform( text ); 'hola munda'; end
end
def self.translate( text )
t = Translator.new
t.perform( text )
end
end
또한 Module.private_class_method더 많은 의도를 표현했습니다.
module Foo
def self.included(base)
base.instance_eval do
def method_name
# ...
end
private_class_method :method_name
end
end
end
질문의 코드 :
module Thing
def self.pub; puts "Public method"; end
def self.priv; puts "Private method"; end
private_class_method :priv
end
Ruby 2.1 이상 :
module Thing
def self.pub; puts "Public method"; end
private_class_method def self.priv; puts "Private method"; end
end
module Writer
class << self
def output(s)
puts upcase(s)
end
private
def upcase(s)
s.upcase
end
end
end
Writer.output "Hello World"
# -> HELLO WORLD
Writer.upcase "Hello World"
# -> so.rb:16:in `<main>': private method `upcase' called for Writer:Module (NoMethodError)
"포함"메서드를 사용하여 모듈이 혼합 될 때 멋진 작업을 수행 할 수 있습니다. 이 원하는대로 수행합니다.
module Foo
def self.included(base)
class << base
def public_method
puts "public method"
end
def call_private
private_method
end
private
def private_method
puts "private"
end
end
end
end
class Bar
include Foo
end
Bar.public_method
begin
Bar.private_method
rescue
puts "couldn't call private method"
end
Bar.call_private
불행히도 인스턴스 private메소드에만 적용됩니다. 클래스에서 비공개 "정적"메서드를 얻는 방법은 다음과 같은 작업을 수행하는 것입니다.
class << self
private
def foo()
....
end
end
나는 모듈에서 이것을 해본 적이 없다.
좋은 방법은 이렇게
module MyModule
class << self
def public_method
# you may call the private method here
tmp = private_method
:public
end
private def private_method
:private
end
end
end
# calling from outside the module
puts MyModule::public_method
Rails에서이 작업을 통해 찾은 최고의 패턴은 private 메서드를 갖고 싶은 모듈을 포기하고 대신 Singleton 클래스를 사용하는 것입니다. 옳지 않은 느낌이 들지만 작동 하고이 질문에서 본 다른 예보다 더 깨끗해 보입니다.
이것에 대한 다른 의견을 듣고 싶습니다.
예:
ErrorService.notify("Something bad happened")
class ErrorService
include Singleton
class << self
delegate :notify, to: :instance
end
def notify(message, severity: :error)
send_exception_notification(message)
log_message(message, severity)
end
private
def send_exception_notification(message)
# ...
end
def log_message(message, severity)
# ...
end
end
클래스 변수 / 상수 내에 메서드를 람다로 저장하는 것은 무엇입니까?
module MyModule
@@my_secret_method = lambda {
# ...
}
# ...
end
테스트 용 :
UPD : 6 년 후이 코드를 대대적으로 업데이트하면 private 메서드를보다 깔끔하게 선언 할 수 있습니다.d
module A
@@L = lambda{ "@@L" }
def self.a ; @@L[] ; end
def self.b ; a ; end
class << self
def c ; @@L[] ; end
private
def d ; @@L[] ; end
end
def self.e ; c ; end
def self.f ; self.c ; end
def self.g ; d ; end
def self.h ; self.d ; end
private
def self.i ; @@L[] ; end
class << self
def j ; @@L[] ; end
end
public
def self.k ; i ; end
def self.l ; self.i ; end
def self.m ; j ; end
def self.n ; self.j ; end
end
for expr in %w{ A.a A.b A.c A.d A.e A.f A.g A.h A.i A.j A.k A.l A.m A.n }
puts "#{expr} => #{begin ; eval expr ; rescue => e ; e ; end}"
end
여기에서 볼 수 있습니다.
A.a => @@L
A.b => @@L
A.c => @@L
A.d => private method `d' called for A:Module
A.e => @@L
A.f => @@L
A.g => @@L
A.h => private method `d' called for A:Module
A.i => @@L
A.j => @@L
A.k => @@L
A.l => @@L
A.m => @@L
A.n => @@L
1) @@L외부에서 액세스 할 수 있지만, 거의 모든 곳에서 액세스 할 수 없습니다
)이 class << self ; private ; def성공적으로 방법을 만드는 d외부에서 액세스 할 수와와 내부에서 self.이 이상해 -하지만 그것없이
3) private ; self.및 private ; class << self방법은 비공개로하지 않습니다 - 그들은 액세스 할 수있는 두 유무에 관계없이self.
개인 모듈 또는 클래스 만들기
상수는 결코 비공개가 아닙니다. 그러나 상수에 할당하지 않고 모듈이나 클래스를 만들 수 있습니다.
따라서 대안 :private_class_method은 개인 모듈 또는 클래스를 만들고 여기에 공용 메서드를 정의하는 것입니다.
module PublicModule
def self.do_stuff(input)
@private_implementation.do_stuff(input)
end
@private_implementation = Module.new do
def self.do_stuff(input)
input.upcase # or call other methods on module
end
end
end
용법:
PublicModule.do_stuff("whatever") # => "WHATEVER"
Module.new 및 Class.new 문서를 참조하십시오 .
참고 URL : https://stackoverflow.com/questions/318850/private-module-methods-in-ruby
'IT' 카테고리의 다른 글
| Flexbox 열을 왼쪽과 오른쪽으로 정렬하는 방법은 무엇입니까? (0) | 2020.08.21 |
|---|---|
| Java에서 INI 파일을 구문 분석하는 가장 쉬운 방법은 무엇입니까? (0) | 2020.08.21 |
| Facebook에서 공유를 구현하는 동안 특정 이미지를 축소판으로 표시하는 방법은 무엇입니까? (0) | 2020.08.21 |
| "오류 : / 개발자에 개발자가 없습니다"를 어떻게 진단 할 수 있습니까? (0) | 2020.08.21 |
| ASP.NET Web API에서 ModelState 유효성 검사 처리 (0) | 2020.08.21 |