2011-02-03 2 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 = []를 얻을.

새로운 메타 메소드가 metaMethod가 아닌 메소드에 저장되는 것처럼 보입니다. 그렇다면 metaClass.methodsmetaClass.metaMethods의 차이점은 무엇입니까?

답변

6

MetaMethods에는 Groovy에 의해 클래스에 장식되었지만 실제로 클래스의 직접적인 부분이나 상속 구조가 아니거나 metaClass를 통해 클래스에 수동으로 삽입 된 메소드가 포함되어 있습니다.

이들은 DefaultGroovyMethods 클래스에서 정의됩니다. 당신이 인스턴스화하는 객체의 유형에 따라

, 그것은

코드이 수정되는 방법을 보여줍니다 등을 발견, 수집, 각각 같은 대부분 반복자의 메타 만 "진짜"만하고, 공유 :

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에 있습니다. 모든 "실제"메소드는 클래스 자체 또는 상위 클래스 (이 경우 Object)와 metaClass를 직접 설정하기 위해 metaClass와 직접 관련된 몇 가지 그루비 물건뿐만 아니라 getProperty/setProperty 및 invokeMethod 메서드 동작을 재정의 할 수 있습니다.

당신이 존재하는 것을 확인하기 위해 모든 방법을 통해 검색 할 경우, 나는이 같은 것을 사용

def allMethods = (Example.metaClass.methods + Example.metaClass.metaMethods).name.sort().unique() 
관련 문제