2017-08-01 19 views
5

किसी तर्क के बीच अंतर और कोई स्पष्ट हस्ताक्षर वाले ब्लॉक में कोई तर्क देने के लिए पर्ल 6 तरीका क्या है? मेरे पास इसके लिए कोई व्यावहारिक उपयोग नहीं है, लेकिन मैं उत्सुक हूं।क्या यह एक तर्क है या कोई पर्ल 6 ब्लॉक के लिए नहीं है?

कोई स्पष्ट हस्ताक्षर के साथ एक ब्लॉक $_ में मूल्य कहते हैं:

my &block := { put "The argument was $_" }; 

हस्ताक्षर वास्तव में ;; $_? is raw है। यह एक वैकल्पिक तर्क है। @_ चर को ब्लॉक में परिभाषित नहीं किया गया है क्योंकि कोई स्पष्ट हस्ताक्षर नहीं है।

कोई तर्क है, जहां $_ अपरिभाषित किया जाएगा:

&block(); # no argument 

लेकिन वहाँ भी है एक एक तर्क स्थिति है जहाँ $_ अपरिभाषित कर दिया जाएगा। एक प्रकार वस्तु हमेशा अपरिभाषित है:

&block(Int); 

लेकिन, यह में कुछ भी नहीं के साथ एक $_ वास्तव में एक Any है (बजाय, कहते हैं, Nil)।

&block(); 
&block(Any); 

यहाँ एक लंबे समय तक उदाहरण है:: मैं इन दो मामलों के बीच अंतर नहीं बता सकता

No argument: 
    .perl is Any 
    Argument is an Any type object 
Empty argument: 
    .perl is Empty 
    Argument is Slip type object 
Nil argument: 
    .perl is Nil 
    Argument is Nil 
Any argument: 
    .perl is Any 
    Argument is an Any type object 
Int argument: 
    .perl is Int 
    Argument is Int type object 

उत्तर

1

चाहते यहाँ मैं यह कैसे हल किया है,। मुझे इसे क्लीनर तरीके से करना अच्छा लगेगा लेकिन भाषा की चतुरता रास्ते में आती है और मुझे इसके आसपास काम करना पड़ता है। यह स्थितित्मक मानकों के लिए काम करता है लेकिन नामित पैरामीटर के लिए गहरे शेंगेन हैं और मैं यहां उनसे निपट नहीं पाऊंगा।

मेरे पास एक और सवाल था, Why does constraining a Perl 6 named parameter to a definite value make it a required value?, जहां उत्तरों ने स्पष्ट किया कि वास्तव में कोई वैकल्पिक पैरामीटर नहीं हैं। ऐसे पैरामीटर हैं जिनके पास डिफ़ॉल्ट मान है और यदि कोई स्पष्ट रूप से असाइन नहीं करता है तो एक निहित डिफ़ॉल्ट मान होता है।

मेरी समस्या का क्रूक्स यह है कि मैं जानना चाहता हूं कि मैंने पैरामीटर को एक मान कब दिया और जब मैंने नहीं किया। मैं इसे एक तर्क या एक स्पष्ट डिफ़ॉल्ट के माध्यम से एक मूल्य देता हूं। एक निहित डिफ़ॉल्ट सही प्रकार का एक प्रकार वस्तु है। यह Any है यदि मैंने एक प्रकार निर्दिष्ट नहीं किया है। उस निहित डिफ़ॉल्ट को निर्दिष्ट किसी भी बाधा को पूरा करना होगा।

पहला लक्ष्य उन कोडों को कसकर बाध्य करना है जो उपयोगकर्ता कोड कोड करते समय आपूर्ति कर सकते हैं। यदि एक अपरिभाषित मान मान्य नहीं है तो उन्हें एक निर्दिष्ट करने की अनुमति नहीं दी जानी चाहिए।

दूसरा लक्ष्य आसानी से कोड में विशेष मामलों को अलग करना है। मैं गहन कोड के कुछ हिस्सों को जानने के लिए विशेष ज्ञान की मात्रा को कम करना चाहता हूं।

मुझे तीसरा मामला मिल सकता है (जहां मुझे पता है कि कोई तर्क या उपयुक्त डिफ़ॉल्ट नहीं है) स्पष्ट रूप से एक विशेष मूल्य असाइन करके जो मुझे पता है कि कुछ और सार्थक चीज़ नहीं हो सकती है। एक मूल्य है जो Any से भी अधिक अर्थहीन है। वह Mu है। यह सभी अपरिभाषित मानों का सबसे अनिर्धारित मान है। AnyMu (अन्य Junction) के दो उपप्रकारों में से एक है, लेकिन आपको सामान्य कोड में अपने मूल्यों में से किसी एक में Mu अंत में कभी नहीं देखना चाहिए। उपयोगकर्ता कोड में अपरिभाषित चीजें Any पर शुरू होती हैं।

मैं एक बाधा उत्पन्न कर सकता हूं जो मुझे इच्छित प्रकार के लिए या Mu के लिए जांचता है और Mu का डिफ़ॉल्ट सेट करता है। अगर मुझे Mu दिखाई देता है तो मुझे पता है कि कोई तर्क नहीं था और यह Mu है क्योंकि मेरी बाधा ने इसे सेट किया है।

चूंकि मैं Mu का उपयोग कर रहा हूं, कुछ ऐसी चीजें हैं जो मैं नहीं कर सकता, जैसे === ऑपरेटर का उपयोग करें। स्मार्ट मिलान काम नहीं करेगा क्योंकि मैं विरासत श्रृंखला का परीक्षण नहीं करना चाहता हूं। मैं सीधे वस्तु के नाम की जांच कर सकते हैं:

my $block := -> 
    $i where { $^a.^name eq 'Mu' or $^a ~~ Int:D } = Mu 
    { 
    say "\t.perl is {$i.perl}"; 

    put do given $i { 
     when .^name eq 'Mu' { "\tThere was no argument" } 
     when Nil    { "\tArgument is Nil"  } 
     when (! .defined and .^name eq 'Any') { 
      "\tArgument is an Any type object" 
      } 
     when .defined { 
      "\tArgument is defined {.^name}" 
      } 
     default { "\tArgument is {.^name}" } 
     } 
    }; 

put "No argument: ";   $block(); 
put "Empty argument: ";  try $block(Empty); # fails 
put "Nil argument: ";  try $block(Nil); # fails 
put "Any type argument: "; try $block(Any); # fails 
put "Int type argument: "; try $block(Int); # fails 
put "Int type argument: "; $block(5); 

अब उन आमंत्रण के सबसे असफल क्योंकि वे सही चीजें निर्दिष्ट नहीं करते।

यदि ये दिनचर्या थे तो मैं कई मामलों के लिए मल्टी बना सकता था लेकिन यह अंत में एक और भी खराब समाधान है। अगर मेरे पास दो पैरामीटर थे तो मुझे चार मल्टीज़ की आवश्यकता होगी। ऐसे तीन पैरामीटर के साथ मुझे छह की आवश्यकता होगी। यह बहुत सारे बॉयलरप्लेट कोड है। लेकिन, ब्लॉक दिनचर्या नहीं हैं, इसलिए यह यहां मंथन है।

2
:

my $block := { 
    say "\t.perl is {$_.perl}"; 

    if $_ ~~ Nil { 
     put "\tArgument is Nil" 
     } 
    elsif ! .defined and $_.^name eq 'Any' { 
     put "\tArgument is an Any type object" 
     } 
    elsif $_ ~~ Any { 
     put "\tArgument is {$_.^name} type object" 
     } 
    else { 
     put "\tArgument is $_"; 
     } 
    }; 

put "No argument: "; $block(); 
put "Empty argument: "; $block(Empty); 
put "Nil argument: "; $block(Nil); 
put "Any argument: "; $block(Any); 
put "Int argument: "; $block(Int); 

सूचना नहीं तर्क और किसी भी तर्क रूपों में एक ही बातें बताते हैं

{ put $_.perl } 

इस प्रकार का समान है: (जो काम नहीं करता है)

-> ;; $_? is raw = CALLERS::<$_> { put $_.perl } 

ब्लॉक के $_ बाहर के लिए डिफ़ॉल्ट is default के बाद से Any, आप $_ में कुछ भी नहीं डाल सकते हैं, तो इससे पहले कि आप समारोह आप Any मिल कहते हैं।


बिल्कुल कुछ इसी तरह जहां आपको बता अंतर एक Capture उपयोग कर सकते हैं प्राप्त करने के लिए: जहाँ तक मुझे पता है

my &foo = -> ;; |C ($_? is raw) { 
    unless C.elems { 
     # pretend it was defined like the first Block above 
     CALLER::<$_> := CALLER::CALLERS::<$_> 
    } 
    my $called-with-arguments := C.elems.Bool; 


    if $called-with-arguments { 
     say 'called with arguments'; 
    } else { 
     say 'not called with arguments'; 
    } 
} 
+0

मुझे वह सब पता है। मैं उस मामले के बारे में पूछ रहा हूं जहां मैंने इसमें 'कोई भी' रखा है। –

+0

@briandfoy यदि आपको इस जानकारी की आवश्यकता है, तो उस अंतर का उपयोग न करें जो अंतर को अदृश्य बनाने के लिए है। –

+1

ऐसा नहीं है कि मुझे इसकी आवश्यकता है। मैं देख रहा हूं कि भाषा कैसे काम करती है और इसकी सीमाएं इसलिए मैं अन्य लोगों को बता सकता हूं कि वे क्या करने में सक्षम नहीं होंगे। –

3

, एक ही रास्ता एक के बिना पारित कर दिया मानकों के संख्या पता करने के लिए स्पष्ट हस्ताक्षर, शरीर के अंदर @_ का उपयोग करना है, जो :(*@_) हस्ताक्षर उत्पन्न करेगा।

my &block := { say "Got @_.elems() parameter(s)" }; 
block;    # Got 0 parameter(s) 
block 42;   # Got 1 parameter(s) 
dd block.signature; # :(*@_) 

हाँ, अच्छे पुराने @_ अभी भी वहाँ अगर आप इसे :-)

+1

यह है कि आप '$ _' में मूल्य नहीं लेना चाहते हैं। और @_ में मान अपरिवर्तनीय हैं। –

संबंधित मुद्दे