여기 검사기와 방법을 포장하는 방법의 간단한 예이다 :
class Foo
def foo(a, b, c)
p a, b, c
end
def bar(a, b)
p a, b
end
validate(:foo, :bar) {|*args, &blk| args.reduce(:+) == 6 }
end
Module#validate
방법은 메소드 이름 목록, 및 그 방법에 대한 검증 로직 블록 걸린다.
foo = Foo.new
foo.foo(1, 2, 3)
# 1
# 2
# 3
foo.bar(2, 4)
# 2
# 4
foo.foo(2, 3, 4)
# [2, 3, 4] (Validator::ValidationError)
foo.bar(2, 3)
# [2, 3] (Validator::ValidationError)
앞에서 볼 수 있듯이 유효성 검사기는 블록의 조건을 통과시키지 않았으므로 마지막 두 번의 호출에서 인수 목록을 거부했습니다.
이것은 실제로 모든 마법을 일으키는 "마법"이며 실제로는 그 마법이 아닙니다. 유효성 검사에 실패하면 raise
의 예외가 발생하고 단순히 super
을 호출하는 버전으로 유효성을 검사하려는 메서드를 재정의하는 module
을 생성합니다. 그런 다음 prepend
모듈을 현재 클래스/모듈에 추가합니다. 즉, validate
메소드 호출이 들어있는 모듈입니다. 기본적으로 그 것입니다.
나는 또한 좋은 루비 시민 및 정제에 모든 일을 마무리하기로 결정했습니다, 그래서 당신은 그것을 사실을
using Validator
활성화 할 말을해야합니다.
module Validator
class ValidationError < ArgumentError; end
refine Module do
def validate(*methods, &validator)
prepend(Module.new do
methods.each do |method|
define_method(method) do |*args, &blk|
raise ValidationError, args.inspect unless yield *args
super(*args, &blk)
end
end
end)
end
end
end
귀하의 질문에 명확하지 않습니다. "수업이나 모듈에 의존"한다는 것은 무엇을 의미합니까? 예제 코드를 포함하도록 질문을 편집 할 수 있습니까? –
여기 왜 데코레이터 패턴을 사용하고 싶은지 궁금합니다. 인수를 인라인으로 검증하지 않는 이유는 무엇입니까? 그렇게하는 것은 약 세 줄 정도입니다. –
이 방법을 사용하는 것만으로는 충분하지 않습니다.이 데코레이터를 사용할 수있는 다른 방법이 있습니다. –