크리스탈 - 플러그인 패턴
5787 단어 crystal
영감
나는 최근에added Lucky to TechEmpower benchmarks 다른 프레임워크가 그렇게 잘 수행하기 위해 무엇을 하고 있는지에 대한 기사/비디오를 찾고 있었습니다. Optimization Techniques Used by the Benchmark Winners이라는 Jeremy Evans의 정말 좋은 강연을 보았습니다. Lucky를 변경하기 위한 목록을 가져오는 대신 그가 자신의 프레임워크를 디자인한 방식에 매료되었습니다Roda . 특히 플러그인을 완전히 사용하여 동작을 확장하고 추가한다는 아이디어가 마음에 들었습니다. 프레임워크의 소스 코드를 볼 기회가 있으면 클래스가 거의 비어 있음을 알 수 있습니다. 모든 동작은 플러그인을 통해 추가됩니다. 이것이 Crystal에서 가능한지 정말 보고 싶었습니다.
도전
Roda에서는 플러그인을 추가할 때 중첩된 모듈을 포함하고 확장합니다.
plugin CustomRender
# becomes...
include(CustomRender::InstanceMethods) if defined?(CustomRender::InstanceMethods)
extend(CustomRender::ClassMethods) if defined?(CustomRender::ClassMethods)
# and more...
또한 요청 및 응답 개체에 모듈을 추가하지만 Crystal로 변환할 때의 문제를 전달하기에 충분한 코드입니다.
defined?
방법이 없습니다 해결책
Crystal은 런타임에 모듈을 포함할 수 없지만 많은 동일한 작업을 수행할 수 있는 매크로가 있습니다. 원래 아이디어는 다음과 같은 매크로를 갖는 것이었습니다.
macro plugin(type)
include {{ type }}::InstanceMethods
extend {{ type }}::ClassMethods
end
그것의 유일한 문제는 Roda가 가진 조건부 측면입니다. 플러그인이 클래스 메소드를 추가할 필요가 없다면 해당 모듈을 정의할 필요가 없고 프레임워크가 이를 처리할 수 있어야 합니다. 내가 찾은 유일한 해결책은 두 번째 매크로에 위임하는 것입니다.
macro extend_self(instance_methods, class_methods)
{% if ims = instance_methods.resolve? %}
include {{ ims }}
{% end %}
{% if cms = class_methods.resolve? %}
extend {{ cms }}
{% end %}
end
macro plugin(type)
extend_self({{ "#{type}::InstanceMethods".id }}, {{ "#{type}::ClassMethods".id }})
end
두 번째 매크로를 사용하는 이유는 모듈이 정의되었는지 확인하기 위해
Path#resolve?
method이 필요하고 이것이 매크로에서 Path
개체를 동적으로 생성하는 유일한 방법이기 때문입니다. 더 좋은 방법이 생각나시면 알려주세요!plugin CustomRender
# becomes...
extend_self(CustomerRender::InstanceMethods, CustomRender::ClassMethods)
# becomes...
include CustomerRender::InstanceMethods
extend CustomRender::ClassMethods
아직 Rod를 Crystal로 실제로 변환하지 못했지만 희망합니다. 또한 그 과정에서 더 많은 게시물을 올릴 수 있기를 바랍니다.
Reference
이 문제에 관하여(크리스탈 - 플러그인 패턴), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/matthewmcgarvey/crystal-plugin-pattern-3imj텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)