2012-01-17 20 views
6

मैं एक रूबी 1.9 सी विस्तार लिख रहा हूँ और मैं रूबी में निम्न कार्य करने के:मैं रुबी 1.9 सी एक्सटेंशन में ब्लॉक को प्रो में कैसे परिवर्तित करूं?

notifier = Notifier.new 
notifier.on 'click' do 
    puts "clicked!" 
end 

अब इस के साथ समस्या यह है कि सी पद्धति पर, मैं केवल "प्राप्त" एक ब्लॉक है, और, जहां तक ​​मुझे पता है, यह एक पैरामीटर भी नहीं है: मैं बस rb_yield के साथ कॉल कर सकता हूं।

तो मेरा सवाल यह है: क्या रूबी 1.9 सी एक्सटेंशन पर एक ब्लॉक को एक प्रोसेस या किसी चीज़ में बदलने के लिए कोई तरीका है, इसलिए मैं इसे अपने मॉड्यूल के अंदर स्टोर कर सकता हूं, और इसे जब भी चाहूं उसे बाद में कॉल कर सकता हूं? एक async कॉलबैक की तरह!

मैंने इसे पहले ही प्रोसेस/लैम्बडास के साथ कार्यान्वित किया है, लेकिन यह केवल बदसूरत है कि ब्लॉक सिंटैक्स का उपयोग न करें।

+5

क्या आपने यह देखा है [http://banisterfiend.wordpress.com/2008/09/25/metaprogramming-in-the-ruby-c-api-part-one-blocks/) आलेख (विशेष रूप से "स्पष्ट ब्लॉक "पैराग्राफ)? यह पुराना हो सकता है लेकिन अन्यथा ऐसा लगता है कि आपको क्या चाहिए। –

+0

क्षमा करें, मैं आपके प्रश्न का उत्तर नहीं दे सकता, क्योंकि मुझे सी और न ही वाईएआरवी सी एपीआई पता नहीं है, लेकिन अन्य पाठकों के लिए स्पष्टीकरण के रूप में, आपका प्रश्न मूल रूप से है: "मैं (& blk) अंत में कैसे करूं सी से ", है ना? –

उत्तर

5

रूबी सी स्रोत में आप proc.c में यह देखेंगे:

एक नया Proc वस्तु, वर्तमान संदर्भ के लिए बाध्य बनाता है:

/* 
* call-seq: 
* proc { |...| block } -> a_proc 
* 
* Equivalent to <code>Proc.new</code>. 
*/ 

VALUE 
rb_block_proc(void) 
{ 
    return proc_new(rb_cProc, FALSE); 
} 

और Proc.new करता है। Proc::new को केवल एक ब्लॉक के साथ एक विधि के भीतर ब्लॉक के बिना बुलाया जा सकता है, जिस स्थिति में ब्लॉक को Proc ऑब्जेक्ट में परिवर्तित किया जाता है। बाद में ब्लॉक/प्रोक कॉल करने के लिए

VALUE p = rb_block_proc(); 
/* and then store `p` somewhere convenient */ 

और फिर,:

तो आप कुछ इस तरह करते हैं होता rb_funcall काफी की सी संस्करण है

rb_funcall(p, rb_intern("call"), 0); 

कि p.send(:call)

+0

ओह मेरे भगवान जो इतना आसान और स्पष्ट था! धन्यवाद! – rubenfonseca

+0

@ रूबेनफोन्सेका: एक बार जब आप जानते हैं कि क्या करना है :) आपको सी एक्सटेंशन लिखने के लिए सी स्रोत की एक grepping- परिचितता की आवश्यकता है। –

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

  • कोई संबंधित समस्या नहीं^_^