簡體   English   中英

為什么missingMethod不適用於Closure?

[英]Why missingMethod is not working for Closure?

UPDATE

我要為讓讀者感到困惑而道歉。 在我完全迷失在代碼中之后,我從Mercurial repo中恢復了所有更改,仔細應用了與以前相同的邏輯 - 並且它有效。 下面的答案幫助我更好地理解(對我來說是新的)概念,為此我給了他們贊成票。

底線:如果在閉包內發生對缺失方法的調用,並且將分辨率設置為DELEGATE_FIRST,則將在委托上調用methodMissing()。 如果沒有 - 檢查你自己的代碼,在某處有一個錯字。

非常感謝!

編輯:好的,既然你已經澄清了你在做什么(有點; - ))

另一種方法(我用於DSL的方法)是解析你的閉包組,通過像這樣的ClosureToMap實用程序進行映射:

// converts given closure to map method => value pairs (1-d, if you need nested, ask)
class ClosureToMap {
    Map map = [:]
    ClosureToMap(Closure c) {
        c.delegate = this
        c.resolveStrategy = Closure.DELEGATE_FIRST
        c.each{"$it"()}
    }
    def methodMissing(String name, args) {
        if(!args.size()) return
        map[name] = args[0]
    }
    def propertyMissing(String name) { name }
}

// Pass your closure to the utility and access the generated map
Map map = new ClosureToMap(your-closure-here)?.map

現在,您可以遍歷地圖,也許可以向適用的MCL實例添加方法。 例如,我的一些域名具有動態查找器,例如:

def finders = {
    userStatusPaid = { Boolean active = true->
        eq {
            active    "$active"
            paid      true
        }
    }
}

我使用ClosureToMap實用程序創建一個映射,然后迭代,將映射鍵(方法,如“userStatus”)和值(在本例中為閉包“eq”)添加到域實例MCL,將閉包委托給我們的ORM,如所以:

def injectFinders(Object instance) {
    if(instance.hasProperty('finders')) {
        Map m = ClosureToMap.new(instance.finders).map
        m?.each{ String method, Closure cl->
            cl.delegate = instance.orm
            cl.resolveStrategy = Closure.DELEGATE_FIRST
            instance.orm.metaClass."$method" = cl
        }
    }
}

這樣在控制器范圍內我可以做,比方說:

def actives = Orders.userStatusPaid()

並且“eq”閉包將委托給ORM,而不是MME發生的域名訂單。

玩弄它,希望我已經給你一些如何解決問題的想法。 在Groovy中,如果你不能單向做,那就試試另一個; - )

祝好運!

原文:您的missingMethod是在字符串元類上定義的; 為了調用它,你需要“someString”.foo()

如果您只是在閉包中單獨調用foo(),它將失敗,無論使用何種委派策略; 即如果你不使用(String)委托,祝你好運。 例如,做“”.foo(),它的工作原理。

我也不完全理解這個問題,為什么你不能訪問閉包的代表? 您正在設置閉包的委托並將調用閉包,這意味着您將可以訪問閉包本身內的委托(並且可以只委托.foo())

不,你不會捕獲一個丟失的方法,並將其重定向到具有元類魔法的委托。
關閉委托是捕捉到這些電話,並使其適應后盾域機會。
這意味着......
您應該使用dsl所需的方法創建自己的委托。
如果它不是為任務設計的,那么不要試圖強制一個類來委托工作,否則代碼會在非時間內變得非常混亂。
在一組專門設計的委托類中保留所有與dsl相關的內容,一切都會突然變得荒謬簡單明了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM