2013-04-24 5 views
7

जैसा कि नीचे रूबी उदाहरण में दिखाया गया है, मैं lambda को Proc के रूप में Proc के तर्कों की गलत संख्या के साथ कॉल नहीं कर सकता क्योंकि यह तर्कों की संख्या के बारे में सख्त है:विधि या लैम्ब्डा को गैर-लैम्ब्डा प्रो में कनवर्ट करने के लिए कैसे करें

# method with no args 
def a; end 

instance_eval(&method(:a)) 
# ArgumentError: wrong number of arguments (1 for 0) 

method(:a).to_proc.call(1, 2, 3) 
# ArgumentError: wrong number of arguments (3 for 0) 

method(:a).to_proc.lambda? 
# => true 

मैं एक Proc है कि या तो एक Proc से एक लैम्ब्डा है या एक Method से कि नहीं है कैसे मिलता है?

+0

जहाँ तक मैं कह सकता हूं, आप एक विधि या लैम्ब्डा को गैर-लैम्ब्डा प्रो में परिवर्तित नहीं कर सकते हैं। आप क्या खत्म करने की कोशिश कर रहे हैं? –

+0

@WallyAltman एक ब्लॉक के कॉलिंग अर्थशास्त्र, तर्कों की संख्या के संबंध में सभी के ऊपर, लेकिन कई अन्य अंतर हैं। – michelpm

उत्तर

2

ऐसा करने का कोई तरीका नहीं है।

बहस के अलावा, मुझे आश्चर्य है कि आप विधि में return से क्या अपेक्षा करेंगे। यह केवल lambda तरीके से व्यवहार कर सकता है ...

यदि आपको वास्तव में ऐसा करना है, तो आपको अपना स्वयं का ब्लॉक बनाना होगा, उदा।

Proc.new{ a } 

एक अधिक सामान्य तरीका के लिए, आप विधि के arity की जाँच करें और केवल आवश्यक पैरामीटर पारित करने के लिए होगा।

+0

मुझे लगता है कि 'रिटर्न', 'अगली' और 'ब्रेक' की वजह से यह असंभव था क्योंकि एक अस्थायी उपाय के रूप में मैं या तो स्प्लिट के साथ लेखन विधियां या उन्हें 'प्रो' वापस कर रहा हूं। क्या सबूत साबित करने का कोई तरीका है? – michelpm

+0

@ मिशेलम: कोई सबूत नहीं, क्षमा करें। –

0

तो जैसे एक गैर लैम्ब्डा Proc में यह लपेटकर कोशिश करें,:

l = lambda {|a,b| puts "a: #{a}, b: #{b}" } 
p = proc {|a,b| l.call(a,b) } 

l.lambda? 
#=> true 
l.arity 
#=> 2 
l.call("hai") 
#=> ArgumentError: wrong number of arguments (1 for 2) 
l.call("hai", "bai", "weee", "womp", "woo") 
#=> ArgumentError: wrong number of arguments (5 for 2) 

p.lambda? 
#=> false 
p.arity 
#=> 2 
p.call("hai") 
#=> a: hai, b: 
p.call("hai", "bai", "weee", "womp", "woo") 
#=> a: hai, b: bai 
0

कन्वर्ट LambdaProc

यहाँ करने के लिए एक काम के आसपास है कि एक lambda या एक Proc और उपयोग में एक method कॉल लपेटता किसी भी तर्क को संभालने के लिए विभाजित करें:

def lambda_to_proc(lambda) 
    Proc.new do |*args| 
    diff = lambda.arity - args.size 
    diff = 0 if diff.negative? 
    args = args.concat(Array.new(diff, nil)).take(lambda.arity) 

    lambda.call(*args) 
    end 
end 

यह हमेशा काम करेगा तर्कों की संख्या से कोई फर्क नहीं पड़ता; अतिरिक्त तर्क गिराए जाएंगे और nil गुम तर्कों को प्रतिस्थापित करेंगे।


उदाहरण:

# lambda with two args 
some_lambda = -> (a,b) { [a, b] } 

# method with no args 
def some_method; "hello!"; end 

lambda_to_proc(some_lambda).call(5) 
# => [5, nil] 

lambda_to_proc(method(:some_method)).call(1,2,3) 
# => "hello!" 

नोट: कोई सीधा रास्ता एक लैम्ब्डा या एक proc करने के लिए एक विधि कॉल कन्वर्ट करने के लिए नहीं है। यह सिर्फ एक कामकाज है और असली सौदा से स्पष्ट रूप से धीमा है (दूसरे में एक कॉल लपेटने के कारण)।

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