Groovy: значение 'this' внутри замыкания

Следующий пример адаптирован из "Groovy в действии"

class Mother {

    Closure birth() {                            
        def closure = { caller ->
            [this, caller]
        }
        return closure
    }
}                    

Mother julia = new Mother()
closure = julia.birth()                                
context = closure.call(this)                             

println context[0].class.name        // Will print the name of the Script class
assert context[1] instanceof Script 

Согласно книге, значение this внутри замыкания является самой внешней областью (т.е. область, в которой объявляется julia). Правильно ли я полагаю, что

  • this внутри замыкания оценивается область, в которой называется замыкание?
  • в приведенном выше закрытии, this и caller относятся к той же области видимости?

Спасибо, Дон

Ответ 1

Взгляните на страницу 144

... это относится к закрытию, а не к объявляющий объект. С этой точки зрения, замыкания для нас играют. Oни делегировать все вызовы методов на так называемый объект делегирования, который по умолчанию считается объявлением объект (то есть владелец). Это делает закрытие выглядит , как если бы прилагаемый код запускается в контексте дня рождения.

За ваши вопросы;

это внутри замыкания оценивается в области, в которой называется замыкание?

из книги они заявляют, что "это относится к закрытию, а не к объявляющему объекту" Но из bertport и моего эксперимента кажется, что "this" фактически является объявляющим объектом.

В любом случае ответ по-прежнему "нет" для вашего вопроса.

в закрытии, показанном выше, это и вызывающий абонент ссылаются на ту же область?

Я боюсь, что нет.

Помните, что на стр. 143 и 144 в Groovy в Action необходимо внести некоторые исправления

http://groovy.canoo.com/errata/erratum/show/5

http://groovy.canoo.com/errata/erratum/show/8

Ответ 2

"this" в значении блока в Groovy всегда (будь то обычный Java-подобный блок или закрытие) окружающего класса (экземпляра). "owner" является свойством Closure и указывает на объект внедрения, который является либо классом (экземпляром), а затем тогда же как "this" или другим закрытием. Я бы забыл об этой предметной области полностью для этой части. Поэтому в приведенном выше правиле правильно, что "this" относится к матери.

И теперь, чтобы усложнить ситуацию... "this", и это неявно, это не то же самое в Groovy. Поэтому, если у вас есть Closure {foo()} и {this.foo()}, вы можете получить разные результаты. this.foo() всегда будет разрешен для класса внедрения, а только foo() будет разрешен с использованием протокола метаданных Groovy (MOP) и может указывать на нечто совершенно другое. Строитель может, например, установить делегат в этом Closure и уловить вызов метода для стандартного конструктора Groovy. В любом случае... поэтому эта часть называется динамическим охватом.

Исторический фон: До Groovy 1.0 "this" был сам объект Closure. Но было изменено, потому что фактически вызов this.foo() стал невозможным, если строитель выполнил захват всех вызовов. то у вас не было способа больше называть локальные методы изнутри строителя. Было много попыток изменить стандартную стратегию решения - и большие эмоциональные дискуссии тоже. Но в конце концов, изменение "this" для ссылки на класс внедрения было простым решением проблемы и в большей степени соответствовало людям, приходящим из Java, и это позволяло вам легко обойти СС, если вы настаиваете.

Ответ 3

{
    def self = ({ owner })()
}

owner: прилагаемый объект (этот или окружающий Closure).

Ответ 4

Саке говорит: "это закрытие, а не объект, где построено замыкание". Но когда мы запускаем этот script, мы обнаруживаем, что это Мать, а не Закрытие.