2016-12-01 22 views
6

रूबी में, निरंतर लुकअप घोंसले से प्रभावित होता है और विधियां उनके घोंसले को बरकरार रखती हैं।रूबी में मुझे विधि का घोंसला कैसे मिल सकता है?

उदाहरण के लिए

, अगर मैं इन मॉड्यूल है:

module Foo 
    module ::A 
    Module.nesting #=> [A, Foo] 
    def Foo.a 
     X 
    end 
    end 
end 

Foo.a #=> 1 

और एक विधि Foo.b[Foo, B] की नेस्टिंग है कि:

module A 
    X = 1 
end 

module B 
    X = 2 
end 

module Foo 
end 

मैं एक विधि Foo.a[A, Foo] की नेस्टिंग है कि परिभाषित कर सकते हैं :

module B 
    module ::Foo 
    Module.nesting #=> [Foo, B] 
    def Foo.b 
     X 
    end 
    end 
end 

Foo.b #=> 2 
Foo::X = 3 

Foo.a #=> 1 <- still resolves to A::X 
Foo.b #=> 3 <- now resolves to Foo::X 

लेकिन मैं एक दिया विधि के घोंसले कैसे तय करते हैं: अगर मैं Foo::X परिभाषितअंतर स्पष्ट हो जाता है?

+0

ईमानदार होने के लिए, मुझे यह भी यकीन नहीं है कि क्यों 'Foo.a' और' Foo.b' परिभाषित और मुख्य में उपलब्ध हैं। –

+0

@EricDuminil मैं ':: Foo' के कारण कहूंगा, यह शीर्ष-स्तर स्थिरांक को संदर्भित करता है। – Stefan

+0

यह नहीं पता था कि शीर्ष स्तर के मॉड्यूल दूसरों में घोंसला जा सकता है, वाह। – akuhn

उत्तर

4

यह काम करेगा:

Foo.method(:a).to_proc.binding.eval('Module.nesting') 
#=> [A, Foo] 

Foo.method(:b).to_proc.binding.eval('Module.nesting') 
#=> [Foo, B] 

रूबी 2.2.1 और 2.3.1 के साथ परीक्षण किया गया। यह रूबी 2.1.5 के साथ काम नहीं करता है।

+1

हां, यह मदद करता है, धन्यवाद! – Stefan

+0

आपने कहा _ "मैं इसे अपने फोन पर परीक्षण नहीं कर सकता" _ - क्या यह एक भाग्यशाली अनुमान था या क्या आप जानते थे कि यह काम करेगा? – Stefan

+2

मान लें कि यह एक शिक्षित अनुमान था, आधिकारिक रूबी दस्तावेज के साथ मदद की। –

2

आप इसके बारे में गलत तरीके से सोच रहे हैं। "विधियों के घोंसले" जैसी कोई चीज नहीं है। Constants कहीं घोंसला कर रहे हैं। नेस्टिंग में मॉड्यूल और कक्षाओं के नाम से जुड़े पथ संकल्प हैं। विधि मॉड्यूल/कक्षा के भीतर निहित हैं (चाहे यह "सामान्य" या सिंगलटन हो)।


जहां कोई विधि रखी जाती है वह अर्थात् है। self के समान एक अवधारणा है, जो निर्धारित करती है कि एक विधि को परिभाषित किया जाएगा, जिसे डिफ़ॉल्ट परिभाषा कहा जाता है। इसके लिए कोई कीवर्ड है, लेकिन यह करने के लिए बराबर है:

kind_of?(Module) ? name : self.class.name 

कहाँ एक निरंतर रखा गया है/खोजा लिए विशुद्ध रूप से वाक्य है। जब आप X का उल्लेख है, यह कम से कम बिट परवाह नहीं करता है अगर आप इसे रखा एक विधि या नहीं:

DEEP_MIND = Object.new 

module Foo 
    X = 42 
end 

module Foo 
    module Bar 
    def DEEP_MIND.talk 
     p X 
    end 
    end 
end 

DEEP_MIND.talk # => 42 

module Foo::Bar 
    def DEEP_MIND.talk 
    p X 
    end 
end 

DEEP_MIND.talk # => uninitialized constant 

सभी यह परवाह करता है के बारे में है क्या "वर्तमान नेस्टिंग" कोड की लाइन पर जहां इसका संदर्भ देने की कोशिश की।


अब, अगर आप वास्तव में"विधि के शरीर के अंदर वर्तमान नेस्टिंग" चाहते थे, तो आप किसी तरह नाटक करने के लिए आप वास्तव में देखते हैं की जरूरत है।

अफसोस की बात है, मुझे नहीं लगता कि @Eric's answer में दिखाए गए किसी भी अन्य तरीके से कोई अन्य तरीका नहीं है। instance_eval/instance_exec के साथ ब्लॉक का उपयोग करने से आपको ब्लॉक की परिभाषा कहां से घोंसला मिल जाएगी।

+0

_ »ऐसी कोई चीज नहीं है जैसे" तरीकों का घोंसला "« _ - लेकिन किसी विधि का मूल्यांकन करने के लिए, रूबी को अपने घोंसले को जानना है। मेरे उदाहरण में, 'Foo.b' पहले' बी :: एक्स' और बाद में 'Foo :: X' तक हल हो जाता है। यह स्थिर रूप से ':: बी :: एक्स' को हल नहीं करता है, यह इसके निर्माण के बिंदु पर घोंसले का सम्मान करता है, यानी '[फू, बी]'। – Stefan

+0

@Stefan * "लेकिन एक विधि का मूल्यांकन करने के लिए, रूबी को अपने घोंसले को जानना है" * - वास्तव में नहीं। यह सिर्फ यह जानने की जरूरत है कि किस वस्तु पर इसका आह्वान किया गया है। निरंतर विधि द्वारा हल नहीं किया जाता है। यह कोड में वर्तमान संदर्भ द्वारा हल किया गया है। ऐसा ही होता है कि वर्तमान संदर्भ/बंद करने के लिए तरीकों का एक सुविधाजनक तरीका है - 'बाध्यकारी'। जहां भी आप हैं, विधि या नहीं, वर्तमान मॉडलिंग को 'मॉड्यूल.नेस्टिंग' के माध्यम से एक्सेस किया जा सकता है। यह वर्तमान बाध्यकारी का उपयोग करता है। 'binding.eval ('मॉड्यूल.नेस्टिंग') 'यह दिखाने के लिए एक अलग बाध्यकारी का उपयोग करता है कि इसका एक अलग संदर्भ है। – ndn

+0

@Stefan, ठीक है, आप कह सकते हैं कि एक विधि जानता है कि यह बाध्यकारी है, और बाध्यकारी (जहां भी आप हैं, विधि या नहीं) वर्तमान घोंसले को जानता है। इस अर्थ में एक विधि वर्तमान घोंसले को जानता है जहां इसे परिभाषित किया गया था। लेकिन यह केवल आकस्मिक है, यह विचार नहीं है कि तरीकों को स्थिरांक के समान ही घोंसला दिया जाता है। – ndn

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