2015-09-03 2 views
2

Я новичок в Gradle/Groovy, и я сталкиваюсь с проблемами с переменным разрешением имени в вложенных замыканиях. У меня есть собственный класс задач, который определяет некоторые свойства, и я создаю потенциально несколько задач этого типа, используя закрытие. Это замыкание определяет переменную, названную так же, как одно из свойств в пользовательском классе задачи, и я сталкиваюсь с каким-то нечетным поведением, которое, похоже, противоречит тому, что определено в руководстве по языку Groovy. Может ли кто-нибудь ответить на вопросы в коде ниже?Недостаток путаницы с зазором/Groovy

class Something extends DefaultTask { 
    def thing = "a" 
} 
/* 
def thing = "b" // produces the error message: 
       // > Could not find method b() for arguments [[email protected]] on root project 'gradle-test'. 
       // ...why? 
*/ 
(1..1).each { 
    def thing = "c" 
    task ("someTask${it}", type: Something) { 
     println resolveStrategy == Closure.DELEGATE_FIRST // prints "true" 
     println delegate.class // prints "class Something_Decorated" 
     println thing // prints "c" shouldn't this be "a" since it's using DELEGATE_FIRST? 
     /* 
     println owner.thing // produces the error message: 
          // > Could not find property 'thing' on root project 'gradle-test' 
          // shouldn't the "owner" of this closure be the enclosing closure? 
          // in that case shouldn't this resolve to "c" 
     */ 
    } 
} 


EDIT: По какой-то причине после изменения всех def в String, а затем обратно в def я больше не могу реплицировать на def thing = "b" линии производства, что странно ошибка

ответ

1

Кодовые печатает c потому что переменная с именем thing объявлена ​​в лексической области закрытия. Это означает, что закрытие может просто использовать значение этой переменной. Что будет работать:

  1. Переименование переменной thing, определенной в закрытии.

  2. Явное со ссылкой на thing через delegate:

    println delegate.thing

+0

поэтому он будет использовать только стратегию делегирования (упомянутое в разделе [3.2.4 Руководства Groovy Language] (Http: // www.groovy-lang.org/closures.html)), если он не может сначала найти имя в лексической области закрытия? – SamYonnou

+0

Насколько я понял, да. – Opal

+1

Хорошо, что имеет смысл. Кроме того, эта странная ошибка, с которой я столкнулась в строке 'def thing =" b "', кажется, ушла после того, как я сменил все 'def' на' String', а затем вернулся в 'def' (теперь он просто передает ошибка в том, что 'thing' уже определен в строке' def thing = "c", что делает намного больше смысла), поэтому я собираюсь предположить, что это была какая-то странная ошибка или что-то в этом роде. – SamYonnou

Смежные вопросы