next
-
Имя
- next, nextto — вызов реализаций метода суперкласса
- Синтаксис
- Описание
- Цепочка методов
- Порядок поиска методов
- Фильтры
- Примеры
- См. также
- Ключевые слова
Имя
next, nextto — вызов реализаций метода суперклассаСинтаксис
package require TclOOnext ?arg ...?
nextto class ?arg ...?
Описание
Команда next используется для вызова реализаций метода классом, суперклассом или миксином, переопределёнными текущим методом. Она может использоваться только изнутри метода. Она также используется внутри фильтров для обозначения момента, когда фильтр вызывает фактическую реализацию (фильтр может решить не идти по цепочке и может обработать результаты прохождения по цепочке методов по своему усмотрению). Результатом команды next является результат следующего метода в цепочке методов; если в цепочке методов больше нет методов, результатом next будет ошибка. Аргументы, arg, для next — это аргументы, которые передаются следующему методу в цепочке.Команда nextto аналогична команде next, за исключением того, что она принимает дополнительный аргумент class, который идентифицирует класс, чья реализация текущей цепочки методов (см. info object call) должна быть использована; выбранная реализация метода будет предоставлена указанным классом, и она должна ссылаться на существующий вызов, который не является фильтром и находится дальше по цепочке, чем текущая реализация.
Цепочка методов
Когда вызывается метод объекта, происходят несколько этапов:- Исследуется структура объекта, его класс, суперклассы, фильтры и миксины, чтобы создать цепочку методов, которая содержит список реализаций методов, которые нужно вызвать.
- Вызывается первая реализация метода в цепочке.
- Если эта реализация метода вызывает команду next, вызывается следующая реализация метода (с аргументами, которые были переданы в next).
- Результатом вызова метода в целом является результат внешней реализации метода; внутренние реализации методов возвращают свои результаты через next.
- Цепочка методов кешируется для последующего использования.
Порядок поиска методов
При построении цепочки методов реализации методов ищутся в следующем порядке:- В классах, смешанных в объект, в порядке обхода классов. Список миксинов проверяется в естественном порядке.
- В классах, смешанных в классы объекта, с источниками смешивания, которые ищутся в порядке обхода классов. Внутри каждого класса список миксинов обрабатывается в естественном порядке.
- В самом объекте.
- В классе объекта.
- В суперклассах класса, следуя за каждым суперклассом в порядке обхода в глубину в естественном порядке списка суперклассов.
Любая конкретная реализация метода всегда появляется поздно в результирующем списке реализаций, насколько это возможно; это означает, что если какой-то класс, A, смешан как в класс, B, так и является суперклассом B, экземпляры B всегда будут относиться к A как к суперклассу с точки зрения наследования. Это верно даже при косвенной обработке множественного наследования.
Фильтры
Когда у объекта есть список имён фильтров, установленных на нём, или он является экземпляром класса (или имеет смешанный класс), у которого есть список имён фильтров, установленных на нём, перед каждым вызовом любого метода фильтры обрабатываются. Реализации фильтров находятся в порядке обхода классов, так же как и списки имён фильтров (каждый из которых просматривается в естественном порядке списка). Явное вызывание метода, используемого как фильтр, вызовет этот метод дважды, один раз как фильтр и один раз как обычный метод.Каждый фильтр должен сам решать, разрешить ли дальнейшее выполнение до правильной реализации метода (что он делает, вызвав команду next, поскольку фильтры вставляются в начало цепочки вызова метода) и отвечает за возврат результата next.
Фильтры вызываются при обработке вызова метода unknown из-за невозможности найти реализацию метода, но не при вызове конструкторов или деструкторов. (Обратите внимание, однако, что метод destroy — это обычный метод, и фильтры вызываются как обычно, когда он вызывается.)
Примеры
Этот пример демонстрирует, как использовать команду next для вызова реализации (супер)класса метода. Скрипт:oo::class create theSuperclass {
method example {args} {
puts "in the superclass, args = $args"
}
}
oo::class create theSubclass {
superclass theSuperclass
method example {args} {
puts "before chaining from subclass, args = $args"
next a {*}$args b
next pureSynthesis
puts "after chaining from subclass"
}
}
theSubclass create obj
oo::objdefine obj method example args {
puts "per-object method, args = $args"
next x {*}$args y
next
}
obj example 1 2 3 выводит следующее:
per-object method, args = 1 2 3 before chaining from subclass, args = x 1 2 3 y in the superclass, args = a x 1 2 3 y b in the superclass, args = pureSynthesis after chaining from subclass before chaining from subclass, args = in the superclass, args = a b in the superclass, args = pureSynthesis after chaining from subclass
Этот пример демонстрирует, как создать простой класс кэша, который применяет запоминание к всем вызовам методов объектов, в которые он смешан, и показывает, как это может повлиять на время вычислений:
oo::class create cache {
filter Memoize
method Memoize args {
# Do not filter the core method implementations
if {[lindex [self target] 0] eq "::oo::object"} {
return [next {*}$args]
}
# Check if the value is already in the cache
my variable ValueCache
set key [self target],$args
if {[info exist ValueCache($key)]} {
return $ValueCache($key)
}
# Compute value, insert into cache, and return it
return [set ValueCache($key) [next {*}$args]]
}
method flushCache {} {
my variable ValueCache
unset ValueCache
# Skip the caching
return -level 2 ""
}
}
oo::object create demo
oo::objdefine demo {
mixin cache
method compute {a b c} {
after 3000 ;# Simulate deep thought
return [expr {$a + $b * $c}]
}
method compute2 {a b c} {
after 3000 ;# Simulate deep thought
return [expr {$a * $b + $c}]
}
}
puts [demo compute 1 2 3] → prints "7" after delay
puts [demo compute2 4 5 6] → prints "26" after delay
puts [demo compute 1 2 3] → prints "7" instantly
puts [demo compute2 4 5 6] → prints "26" instantly
puts [demo compute 4 5 6] → prints "34" after delay
puts [demo compute 4 5 6] → prints "34" instantly
puts [demo compute 1 2 3] → prints "7" instantly
demo flushCache
puts [demo compute 1 2 3] → prints "7" after delay См. также
oo::class, oo::define, oo::object, self
Licensed under Tcl/Tk terms
https://www.tcl.tk/man/tcl/TclCmd/next.htm
Licensed under Tcl/Tk terms
https://www.tcl.tk/man/tcl/TclCmd/next.htm