2012-01-26 12 views
5

हम मूस कक्षाओं का उपयोग करते हैं जो विभिन्न आउटपुट स्वरूपों में इटरेटर को क्रमबद्ध करते हैं। हम एक विशेषता के रूप में इटरेटर का वर्णन:मूस प्रकार की बाधाओं के साथ धन्य कोडरफ्स का उपयोग

has iterator => (
    is => 'ro', 
    isa => 'CodeRef', 
    required => 1, 
); 

यह अब तक ठीक काम किया है, लेकिन हम हाल ही में Iterator::Simple का उपयोग कर बाद में खपत के लिए iterators तैयार करने के लिए किया गया है। इसका मतलब यह है कि हम इस लिखने के बारे में जा सकते हैं कि:

has iterator => (
    is => 'ro', 
    isa => 'CodeRef|Iterator::Simple::Iterator', 
    required => 1, 
); 

और हमारे serializers इटरेटर वर्ग को सही ढंग से स्वीकार करने के लिए अनुमति देते हैं। हालांकि, यह एक अपूर्ण समाधान प्रतीत होता है।

क्या मूस में कोई बाधा निर्दिष्ट करने के लिए है कि विशेषता को कॉल करने योग्य होना चाहिए? मुझे संदेह है कि Moose::Util::TypeConstraints के साथ पर overload::Overloaded का उपयोग करना संभव है, लेकिन मैं जानना चाहता हूं कि किसी ने पहले से ऐसा करने के लिए मॉड्यूल बनाया है या यदि इसके लिए परीक्षण करने के लिए एक मूस-मानक तरीका है।

उत्तर

4

CodeRef केवल असंबद्ध कोड संदर्भों की अनुमति देता है। सौभाग्य से, अपने स्वयं के प्रकार बनाना आसान है।

Callable परिभाषित करें जिन्हें आप नीचे देख, तो CodeRef के बजाय इसका उपयोग। यह निम्नलिखित की अनुमति देता है:

  • असंबद्ध कोड संदर्भ।
  • धन्य कोड संदर्भ।
  • ऑब्जेक्ट्स जो कोड संदर्भ होने का नाटक करते हैं (यानी वे &{} ओवरलोड करते हैं)।

use Moose::Util::TypeConstraints; 
use overload  qw(); 
use Scalar::Util qw(); 

subtype 'Callable' 
    => as 'Ref' 
    => where { 
      Scalar::Util::reftype($_) eq 'CODE' 
      || 
      Scalar::Util::blessed($_) && overload::Method($_, "&{}") 
     } 

    # Written such that parent's inline_as needs not be prepended. 
    => inline_as {'(
      (Scalar::Util::reftype('.$_[1].') // "") eq 'CODE' 
      || 
      Scalar::Util::blessed('.$_[1].') && overload::Method('.$_[1].', "&{}") 
     )'}; 

no Moose::Util::TypeConstraints; 
संबंधित मुद्दे