2011-02-03 4 views
5

यदि मैं कक्षा में मेटा विधि जोड़ता हूं, तो मुझे उम्मीद है कि यह Class.metaClass.metaMethods में दिखाई देगी। लेकिन ऐसा लगता है कि यह मामला नहीं है। विशेष रूप से, अगर मैं ऐसा करते हैं:metaClass.methods और metaClass.metaMethods के बीच क्या अंतर है?

class Example { 
    def realFoo() { "foo" } 

} 
Example.metaClass.metaFoo = { -> "foo" } 

def reals = Example.metaClass.methods*.name.grep{it.contains("Foo")} 
def metas = Example.metaClass.metaMethods*.name.grep{it.contains("Foo")} 

println "reals = $reals, metas = $metas" 

मैं reals = [realFoo], metas = [metaFoo] के उत्पादन में उम्मीद करेंगे, लेकिन मैं वास्तव में reals = [realFoo, metaFoo], metas = [] मिलता है।

ऐसा लगता है कि नए मेटा विधियों को तरीकों से संग्रहीत किया जाता है, मेटा मोड नहीं। तो, metaClass.methods और metaClass.metaMethods के बीच क्या अंतर है?

उत्तर

6

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

इन्हें DefaultGroovyMethods कक्षा में परिभाषित किया गया है।

वस्तु आप instantiating रहे हैं के प्रकार पर निर्भर करता है, यह ज्यादातर प्रत्येक की तरह iterators

अपने कोड में इस संशोधन तरीके हैं कि पता चलता है, एकत्रित करते हैं, लगता है, आदि मेटा केवल, "असली" केवल, और साझा:

class Example { 
    def realFoo() { "foo" } 

} 
Example.metaClass.metaFoo = { -> "foo" } 

def reals = Example.metaClass.methods.name.sort().unique() 
def metas = Example.metaClass.metaMethods.name.sort().unique() 

def metaOnly = metas - reals 
def realOnly = reals - metas 
def shared = reals.findAll { metas.contains(it) } 

println """ 
metaOnly = $metaOnly 
realOnly = $realOnly 
shared = $shared 
""" 

परिणाम:

metaOnly = [addShutdownHook, any, asBoolean, asType, collect, dump, each, eachWithIndex, every, find, findAll, findIndexOf, findIndexValues, findLastIndexOf, findResult, getAt, getMetaPropertyValues, getProperties, grep, hasProperty, identity, inject, inspect, is, isCase, iterator, metaClass, print, printf, println, putAt, respondsTo, sleep, split, sprintf, use, with] 
realOnly = [equals, getClass, getProperty, hashCode, metaFoo, notify, notifyAll, realFoo, setProperty, wait] 
shared = [getMetaClass, invokeMethod, setMetaClass, toString] 

metaOnly और साझा सभी पद्धतियों का DefaultGroovyMethods में हैं। सभी "वास्तविक" विधियां कक्षा में ही हैं, या इसके मूल वर्ग (इस मामले में ऑब्जेक्ट), साथ ही मेटा क्लास से संबंधित कुछ ग्रोवी चीजें मेटा क्लास को प्राप्त/सेट करने के साथ-साथ GetProperty/setProperty और invokeMethod जो आपको विधि व्यवहार को ओवरराइड करने की अनुमति देता है।

आप तरीकों की खोज करने के लिए देखने के लिए क्या मौजूद है चाहते हैं, मैं कुछ इस तरह का उपयोग करें:

def allMethods = (Example.metaClass.methods + Example.metaClass.metaMethods).name.sort().unique() 
संबंधित मुद्दे