ActiveModel의 직렬화, 특히 as_json
및 serializable_hash
의 꼬인 웹을 통해 많은 재미를 느낍니다.클래스/모듈을 포함하지 않는 경우에만 모듈에서 메서드를 정의하도록 허용합니다.
내 앱에는 모듈을 포함하여 동작을 공유하는 모델 모음이 많이 있으며, SharedBehavior
이라고합니다.
팀에서는 JSON (레일즈 앱에서 렌더링하기 위해)으로 캐스팅 할 때 모든 클래스가 따라야하는 기본 형식을 결정했지만 일부는 약간 다르게 동작해야합니다. ActiveModel 라이브러리의이 두 메서드에서 이상한 동작으로 인해 모델 자체에 화이트리스트 또는 블랙리스트에 추가 된 속성을 추가하는 작업은이 모듈의 메서드 정의에 의해 무시되고 ActiveModel의 슈퍼 선언에 전달됩니다.
이러한 이유로이 모듈은 모델에서 명시 적으로 재정의되지 않은 경우에만 모델에 정의를 적용합니다 (본질적으로 모듈을 몇 가지 메소드 호출에 대해 조상 체인에서 가져 오십시오),하지만이 모듈에서 여전히 공유 된 동작이 필요합니다.
I 동적 IRB에서 모듈 개재물의 방법을 적용 조건부 이것을 해결 시도 : 제가
in C
in A
될 C.new.foo
의 출력을 기대하지만 그것이
class A
def foo
puts 'in A'
end
end
module D
def self.included(base)
unless base.instance_methods(false).include?(:foo)
define_method(:foo) do
puts 'in D'
super()
end
end
end
end
class B < A
include D
end
class C < A
include D
def foo
puts 'in C'
super
end
end
을이 선언 대신
in C
in D
in A
유일한 다른 생각은 이동하는 것입니다.
- 그것은 암시을 조금 소개 : 다른 모듈에 출력이 논리 및 명시 적으로이 메소드를 오버라이드 (override)하지 않는 (약 54 그들이있다),하지만 몇 가지 단점이 그에게가 모든 클래스에서 해당 모듈을 포함 새 모델에이 모듈이 포함되어있는 경우이 메서드를 재정의하지 않으려면이 모듈을 포함하십시오.
- 모듈에서 이러한 serialization 메서드의 현재 구현은 해당 모듈에서 설정 한 동작 및 특성과 관련이 있으므로 두 번째 모듈은 첫 번째 모듈과 거의 관련이 없지만
SharedBehavior
의 구현 세부 사항을 알고 그에 따라 달라지는 두 번째 모듈을 갖는 것은 직관이 아닙니다.
included
후크에서 전화를 걸 수있는 위의 코드 예제에서 다른 사람이 다른 해결책을 생각해 보거나 어쩌면 나를 감독 할 수 있습니까? (또한 클래스가 foo
메서드를 정의하고 D
모듈을 포함하지만 정확히 동일한 동작을 보인 순서 전환 시도).
필요, 그래서 요약
을하는 것과 같다. 사실 3 분 전에는 이와 비슷한 무언가에 실제로 도착했습니다. 단, 제 솔루션을 제외하고는 private 메소드'define_method'를'base'에 호출했습니다. 나는 아마도 * _eval 메소드를 제거하려고 노력했다. 아마 내 부분에 대한 지식 부족 때문일 것이다. 나는 그들이 매우 불안하고 보안 위험을 초래할 수 있다고 들었습니다. 이와 관련하여 귀하의 모범이 다른가요? –'eval' 메서드는 임의의 코드를 포함 할 수있는 문자열을 전달하는 경우에만 안전하지 않습니다. 이 경우에는 완벽하게 괜찮습니다. 암묵적인 수신기를'D'에서'base'로 변경하는 데 사용합니다. – Max
달콤한. IRB에서 확인되었습니다. 이것은 매우 계몽적인 운동이었습니다. 감사! –