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 |