2010-05-23 11 views
9

स्टैक ओवरफ़्लो पर पहली बार।रूबी या पायथन में कक्षा की अवधारणा को फिर से लिखा जा सकता है?

मैं रूबी या पायथन द्वारा प्रदान की गई कुछ मेटाप्रोग्रामिंग सुविधाओं का उपयोग करने में देख रहा हूं, लेकिन पहले मुझे यह जानने की आवश्यकता है कि वे मुझे किस भाषा को विस्तारित करने की अनुमति देंगे। मुख्य बात यह है कि मुझे कक्षा की अवधारणा को फिर से लिखना है। इसका मतलब यह नहीं है कि मैं रन टाइम के दौरान विशिष्ट कक्षा को फिर से लिखना चाहता हूं, लेकिन मैं कक्षा क्या है, इसकी अपनी अवधारणा बनाना चाहता हूं। यहां एक स्मीज अधिक विशिष्ट होने के लिए, मैं कुछ ऐसा करना चाहता हूं जो है जो लोग आम तौर पर कक्षा कहते हैं, लेकिन मैं एक "open world" धारणा का पालन करना चाहता हूं। सामान्य वर्गों की "बंद दुनिया" में, अगर मैं कुत्ते को पशु के उप-वर्ग होने के लिए कुत्ते का उप-वर्ग बनने की घोषणा करता हूं, तो मुझे पता है कि पूडल फुरकोट का एक प्रकार भी नहीं होने वाला है। हालांकि, एक खुली दुनिया कक्षा में, फिर मैंने जो पूडल ऑब्जेक्ट परिभाषित किया है वह हो सकता है और हो सकता है कि फुरकोट प्रकार का ऑब्जेक्ट न हो और हम निश्चित रूप से तब तक नहीं जान पाएंगे जब तक कि मैं समझाऊं कि मैं पूडल पहन सकता हूं। (गरीब पूडल।) यह सब एक अध्ययन के साथ करना है जो मैं ओडब्लूएल ऑटोलॉजीज से संबंधित कर रहा हूं।

बस इतना ही पता है, मैंने ऑनलाइन जानकारी खोजने की कोशिश की है, लेकिन यहां शर्तों के अधिभार के कारण मुझे कुछ भी उपयोगी नहीं मिला है।

सुपर धन्यवाद, जॉन

अद्यतन: मैं बस कक्षा की मेरी खुली दुनिया अवधारणा के लिए एक अच्छा उपयोग के मामले के बारे में सोचा। शायद यह वास्तव में क्या करना चाहता है की बेहतर समझ प्रदान करेगा। मैं इसे परिभाषित करने के बजाय कक्षा का "वर्णन" करने में सक्षम होना चाहता हूं। उदाहरण के लिए, मैं यह कहने में सक्षम होना चाहता हूं कि एक कुत्ता कुछ भी है जिसमें ए) चार पैर हैं बी) छाल। फिर मैं अनिर्दिष्ट कक्षा का एक वस्तु बनाने में सक्षम होना चाहता हूं, और वर्णन करता हूं कि इस ऑब्जेक्ट में चार पैर हैं। इस बिंदु पर ऑब्जेक्ट अभी भी अनिर्दिष्ट प्रकार का है। तब मैं कहना चाहता हूं कि वस्तु छाल जाती है। इस बिंदु पर, वस्तु एक कुत्ते (संभवतः अन्य चीजों के बीच) के रूप में जाना जाएगा।

+2

क्या यह आपके बाद के कई विरासत हो सकता है? इससे 'पूडल' को 'कुत्ते' और 'फरकोट' दोनों का उप-वर्ग होना चाहिए, और नतीजतन, यह पता लगाना कि 'पूडल' 'कुत्ते 'का उप-वर्ग है, यह संभावना को बाहर नहीं करता है कि यह' FurCoat'। –

+1

ऐसा लगता है कि आप कक्षा को संशोधित करने के इस विचार पर भी ठीक हो गए हैं। वर्ग प्रकारों की बजाय फ़ील्ड की तुलना करने के लिए रुबी में 'is_a?' कैसे काम करता है यह बदलना संभव है और जो भी आप चाहते हैं उसे करना चाहिए। बतख टाइपिंग के लिए –

उत्तर

7

मैं समीर से सहमत हूं कि यह सिर्फ बतख टाइपिंग की तरह लगता है। आपको परवाह करने की ज़रूरत नहीं है कि 'ऑब्जेक्ट' वास्तव में 'किस प्रकार' है, आपको केवल उस वस्तु से परेशान होने की आवश्यकता है जो 'ऑब्जेक्ट' कर सकता है। यह रूबी और पायथन दोनों में सच है।

हालांकि तुम सच में कक्षाओं के प्रकार की जाँच कर रहे हैं और आप वास्तव में भी एक FurCoat कार्यावधि में होना एक Poodle वस्तु वैकल्पिक रूप से की आवश्यकता है, तो जिस तरह से रूबी में यह करने के लिए Poodle वस्तु में एक FurCoat मॉड्यूल Mixin के लिए है , के रूप में इस प्रकार है:

class Poodle; end 
module FurCoat; def wear; end; end 

my_poodle = Poodle.new 
my_poodle.is_a?(Poodle) #=> true 
my_poodle.is_a?(FurCoat) #=> false 
my_poodle.wear #=> NoMethodError 

# now we mix in the FurCoat module 
my_poodle.extend(FurCoat) 

# my_poodle is now also a FurCoat 
my_poodle.is_a?(Poodle) #=> true (still) 
my_poodle.is_a?(FurCoat) #=> true 
my_poodle.wear #=> the wear method now works 

संपादित (आपके अपडेट प्रश्न के कारण):

तुम अब भी Class के पुनर्लेखन के लिए प्राप्त करने के लिए आप क्या चाहते हैं, तो आप सिर्फ ne की जरूरत नहीं है kind_of? और is_a? (और संभावित रूप से instance_of?) रूबी के Kernel मॉड्यूल पर बंदर-पैच बंद करें। यह आसानी से किया के बाद से रूबी खुला वर्गों है:

class Module 
    def obj_implements_interface?(obj) 
     false 
    end 
end 

module Kernel 
    alias_method :orig_is_a?, :is_a? 

    def is_a?(klass) 
     orig_is_a?(klass) || klass.obj_implements_interface?(self) 
    end 
end 

और फिर प्रत्येक वर्ग के लिए परिभाषित करते हैं (या मॉड्यूल) क्या यह एक वस्तु इसके इंटरफेस को लागू करने के लिए इसका मतलब है:

class Dog 
    def self.obj_implements_interface?(obj) 
     obj.respond_to?(:bark) && obj.respond_to?(:num_legs) && obj.num_legs == 4 
    end 
end 

module FurCoat 
    def self.obj_implements_interface?(obj) 
     obj.respond_to?(:wear) 
    end 
end 

अब यह परीक्षण:

my_poodle = Poodle.new 
my_poodle.is_a?(FurCoat) #=> false 

# now define a wear method on my_poodle 
def my_poodle.wear; end 
my_poodle.is_a?(FurCoat) #=> true 
+0

का उपयोग कर सकता है सबसे पहले, मैं स्टैक ओवरफ्लो और आपके साथ लोगों से बहुत प्रभावित हूं। मैं काटने के लिए जाता हूं और मैं वापस आ जाता हूं और मेरे पास 63 विचार हैं और बूट के कुछ सुंदर समझदार जवाब हैं! तो समीर और बनिस्टर, आप लोग मुझे आवश्यक कार्यक्षमता के करीब * करीब * प्राप्त कर रहे हैं, लेकिन मुझे नहीं लगता कि आप इसे सभी तरह से बना सकते हैं। मैं बतख टाइपिंग नहीं कर सकता क्योंकि अगर यह उड़ सकता है, तो यह एक विमान नहीं है। वास्तविक प्रकार महत्वपूर्ण है, यह सिर्फ अपूर्ण रूप से ज्ञात है।मैं मिश्रण नहीं कर सकता क्योंकि मुझे कभी-कभी * अनुमान लगाया जाना चाहिए कि यह भी निर्दिष्ट किए बिना फुरकोट है। मुझे वास्तव में कक्षा – JnBrymn

+0

को फिर से लिखने में सक्षम होना चाहिए। यह वास्तव में मुझे परिणाम के करीब ले जाता है जो मुझे चाहिए। हालांकि मैं वास्तव में चाहता हूं कि मुझे अपनी इकाई बनाने की आजादी होनी चाहिए जो वर्ग इकाई की नकल करता है। हालांकि, ऐसा लगता है कि उस संभावना के खिलाफ सर्वसम्मति बढ़ रही है। – JnBrymn

8

मुझे duck typing जैसा लगता है। बस तरीकों आप चाहते हैं घोषित करने और याद रखें कि यह अनुमति से माफी पूछने के लिए आसान है:

try: 
    poodle.wear() 
except (AttributeError, TypeError): 
    pass 
+0

+1 शायद ओपी –

2

अजगर में आप क्रम में एक वर्ग के inheritence बदल सकते हैं, लेकिन हर निश्चित समय पर एक वर्ग एक और की एक उपवर्ग नहीं है एक अन्यथा घोषित किए जाने तक। कोई "हो सकता है या नहीं" - उसे टर्नरी लॉजिक की आवश्यकता होगी जो पाइथन समर्थन नहीं करता है। लेकिन निश्चित रूप से आप पाइथन कक्षाओं के लिए ओडब्लूएल ऑटोलॉजीज को मैप करने के लिए अपना "इज़-ए" और "हैस-ए" फ़ंक्शन लिख सकते हैं।

1

मुझे लगता है कि एक वर्ग संरचना पर भरोसा है, चाहे कितना गतिशील हो, एक खुली शब्द धारणा के साथ जानकारी का प्रतिनिधित्व करते समय एक कदम पीछे की तरफ है।

ओडब्ल्यूए के साथ उपयोग किए जाने वाले उदाहरणों के रूप में कार्यरत टेम्पलेट्स और ऑब्जेक्ट्स के रूप में कार्यरत कक्षाएं बिल्कुल कोई लाभ नहीं देती हैं। एक व्यक्ति वर्ग पर विचार करें जहां हम ज्ञान को एन्कोड करते हैं कि एक व्यक्ति के पास 2 पैर होते हैं। हालांकि, हम यह नहीं समझ सकते कि व्यक्ति के उदाहरण में दो पैर होंगे, क्योंकि व्यक्ति की विकलांगता हो सकती है।

यदि वर्ग गुणों का उपरोक्त उदाहरण में कुछ भी मतलब नहीं है, तो जानकारी को एन्कोड करने के लिए उन्हें या किसी अन्य पदानुक्रमित संरचना का उपयोग करने में थोड़ा सा बिंदु दिखाई देता है।

+0

मुझे यहां स्पष्टीकरण की आवश्यकता है कि, अभी के लिए, मैं इस बात से चिंतित नहीं हूं कि मेरे इरादे उचित हैं या नहीं। इसके बजाय, मैं सिर्फ यह जानना चाहता हूं कि मौजूदा क्लास इकाई को प्रतिस्थापित करने के लिए मैं * क्लास-जैसी * इकाई बनाने के लिए रुबी का उपयोग कर सकता हूं या नहीं। कहा जा रहा है कि आपके पास कुछ अच्छे अंक हैं, और यहां तक ​​कि जैसे मैंने "कुत्ते के 4 पैर" उदाहरण बनाए हैं, मुझे एहसास हुआ कि यह अत्यधिक सरल था। हालांकि मेरे पास कुछ और चीजें हैं जो अभी भी खुली दुनिया की कक्षा बनाने में मुझे बहुत रूचि देती हैं। – JnBrymn

6

नहीं, आप Ruby में ऐसा नहीं कर सकते हैं। रूबी में, ऑब्जेक्ट मॉडल को language specification में बेक किया गया है और प्रोग्राम के भीतर से (और निश्चित रूप से संशोधित) तक पहुंच योग्य नहीं है। यहां तक ​​कि Rubinius में, जो रुबी में अधिकतर रूबी कार्यान्वयन है, और अद्भुत मेटाप्रोग्रामिंग क्षमताओं के साथ जो रुबी विनिर्देश प्रदान करता है उससे कहीं अधिक है, the fundamental primitives are hardwired in C++ में से कुछ।

मैं Python से गहराई से परिचित नहीं हूं, लेकिन मुझे यकीन है कि यह वही तरीका है, यहां तक ​​कि PyPy में भी।

आप करना है, Smalltalk में है कि संशोधित करने (या उपवर्गीकरण) the Behavior class, जो Class की सुपर क्लास है और दोनों वर्गों और metaclasses के व्यवहार को परिभाषित करता है के द्वारा सक्षम हो सकता है।

आप निश्चित रूप से ऐसा कर सकते हैं CLOS में, या अधिक सटीक का उपयोग कर CLOS's MOP (Meta-Object Protocol)। आखिरकार, एमओपी क्या है: ऑब्जेक्ट मॉडल को परिभाषित करना।

आपके द्वारा वर्णित की जाने वाली सबसे नज़दीकी ओओ अवधारणा Predicate Classes की प्रतीत होती है।एक अनुमानित वर्ग एक वर्ग है जिसका उदाहरण स्थैतिक रूप से परिभाषित नहीं किया गया है, लेकिन भविष्यवाणियों के एक सेट द्वारा: भविष्यवाणियों के सेट को पूरा करने वाली सभी वस्तुएं कक्षा के उदाहरण हैं, जैसे ही भविष्यवाणी होती है। परिवर्तनीय स्थिति वाली भाषा में, इसका स्पष्ट अर्थ यह है कि ऑब्जेक्ट्स भविष्य में कक्षाओं के अंदर और बाहर "स्थानांतरित" हो सकते हैं क्योंकि उनके राज्य में परिवर्तन होता है। इसका यह भी अर्थ है कि किसी भी समय किसी वस्तु पर कई या कोई अनुमानित कक्षाओं का उदाहरण नहीं हो सकता है।

एकमात्र मुख्यधारा की भाषा ("मुख्यधारा" की व्यापक परिभाषा के लिए) मुझे पता है कि भविष्यवाणी कक्षाएं Factor है।

हालांकि, कृपया ध्यान दें कि यहां तक ​​कि भविष्यवाणियों को परिभाषित किया गया है और एक वस्तु या तो उन्हें पूरा करती है या नहीं। यह पता लगाने की कोई अवधारणा नहीं है कि ऑब्जेक्ट रनटाइम पर भविष्यवाणी करता है या नहीं।

आपको Clojure के ad-hoc taxonomy के विचार में रुचि हो सकती है।

अंतिम, लेकिन निश्चित रूप से कम से कम नहीं, आप Mikel Evins की ऑब्जेक्ट सिस्टम को Categories पर देख सकते हैं।

  1. Protocols
  2. Categories
  3. A peek at Categories
  4. No Kings in Rome
  5. Up pops a reasonable facsimile thereof
  6. Different Categories of Categories
  7. Categories Bugs: श्रेणियाँ का सबसे अच्छा वर्णन, बस कालानुक्रमिक क्रम में ब्लॉग प्रविष्टियों का पालन करना है
  8. Flat Cat in a C3 Vat
  9. Categories 0.2
  10. Bard
  11. Bard intricacies

भविष्य में, श्रेणियाँ पर विकास की सबसे मिकेल की नई भाषा Bard में किया जा रहा है और आप का पालन करते हुए अपनी प्रगति का पालन कर सकते the Categories tag और the Bard tagMikel's new blog पर।

हालांकि, सामान्य रूप से, मैं कहूंगा कि ज्ञान प्रबंधन और ऑब्जेक्ट-ओरिएंटेशन दोनों शब्द वर्ग का उपयोग मुख्य रूप से एक ऐतिहासिक दुर्घटना है। मुझे नहीं लगता कि एक दूसरे के साथ मॉडलिंग एक अच्छा फिट है।

+0

बहुत अच्छी जानकारी Jörg। भविष्यवाणी कक्षा अवधारणा पर ध्यान आकर्षित करने के लिए धन्यवाद। यह वही है जो मैं चाहता हूं, हालांकि एक बड़े अपवाद के साथ कि आपने पहले से ही बताया है: यदि एक वस्तु भविष्यवाणी को पूरा नहीं करती है तो यह एक कक्षा में है तो यह उस वर्ग में नहीं होना जाता है। मैं तीसरा विकल्प बरकरार रखना चाहता हूं जो "मुझे नहीं पता कि वह उस वर्ग में है या नहीं।" तो अगर मैं आगे बढ़ने का फैसला करता हूं तो मुझे अभी भी वस्तु जैसे वर्ग को फिर से बनाना होगा। मैं अभी भी रूबी में ऐसा करने के लिए कुछ तरीके की उम्मीद कर रहा हूं। कक्षा को पुन: प्रोग्राम करने की बजाय, क्या मैं मॉड्यूल से प्राप्त कर सकता हूं और ओपन क्लास बना सकता हूं? – JnBrymn

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