diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2008-05-31 11:41:59 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2008-05-31 11:41:59 (GMT) |
commit | 5b6e0993e188fd16bbb2ec7f54b8b0c7be873629 (patch) | |
tree | b68d9c4cbdbd0775c0419a152b70758bde998ca0 /doc/next.n | |
parent | 032cdb06a8056b84ec16eaace0fc84044c95899a (diff) | |
download | tcl-5b6e0993e188fd16bbb2ec7f54b8b0c7be873629.zip tcl-5b6e0993e188fd16bbb2ec7f54b8b0c7be873629.tar.gz tcl-5b6e0993e188fd16bbb2ec7f54b8b0c7be873629.tar.bz2 |
Implementation of TIP #257. Incomplete due to missing Win build support.
Diffstat (limited to 'doc/next.n')
-rw-r--r-- | doc/next.n | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/doc/next.n b/doc/next.n new file mode 100644 index 0000000..a312764 --- /dev/null +++ b/doc/next.n @@ -0,0 +1,195 @@ +'\" +'\" Copyright (c) 2007 Donal K. Fellows +'\" +'\" See the file "license.terms" for information on usage and redistribution +'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. +'\" +'\" RCS: @(#) $Id: next.n,v 1.1 2008/05/31 11:42:13 dkf Exp $ +'\" +.so man.macros +.TH next n 0.1 TclOO "TclOO Commands" +.BS +'\" Note: do not modify the .SH NAME line immediately below! +.SH NAME +next \- invoke superclass method implementations +.SH SYNOPSIS +.nf +package require TclOO + +\fBnext\fR ?\fIarg ...\fR? +.fi +.BE + +.SH DESCRIPTION +.PP +The \fBnext\fR command is used to call implementations of a method by a class, +superclass or mixin that are overridden by the current method. It can only be +used from within a method. It is also used within filters to indicate the +point where a filter calls the actual implementation (the filter may decide to +not go along the chain, and may process the results of going along the chain +of methods as it chooses). The result of the \fBnext\fR command is the result +of the next method in the method chain; if there are no further methods in the +method chain, the result of \fBnext\fR is the empty string. The arguments, +\fIarg\fR, to \fBnext\fR are the arguments to pass to the next method in the +chain. +.SH "THE METHOD CHAIN" +.PP +When a method of an object is invoked, things happen in several stages: +.IP [1] +The structure of the object, its class, superclasses, filters, and mixins, are +examined to build a \fImethod chain\fR, which contains a list of method +implementations to invoke. +.IP [2] +The first method implementation on the chain is invoked. +.IP [3] +If that method implementation invokes the \fBnext\fR command, the next method +implementation is invoked (with its arguments being those that were passed to +\fBnext\fR). +.IP [4] +The result from the overall method call is the result from the outermost +method implementation; inner method implementations return their results +through \fBnext\fR. +.IP [5] +The method chain is cached for future use. +.SS "METHOD SEARCH ORDER" +.PP +When constructing the method chain, method implementations are searched for in +the following order: +.IP [1] +In the object. +.IP [2] +In the classes mixed into the object, in class traversal order. The list of +mixins is checked in natural order. +.IP [3] +In the classes mixed into the classes of the object, with sources of mixing in +being searched in class traversal order. Within each class, the list of mixins +is processed in natural order. +.IP [4] +In the object's class. +.IP [5] +In the superclasses of the class, following each superclass in a depth-first +fashion in the natural order of the superclass list. +.PP +Any particular method implementation always comes as \fIlate\fR in the +resulting list of implementations as possible. +.SS FILTERS +.PP +When an object has a list of filter names set upon it, or is an instance of a +class (or has mixed in a class) that has a list of filter names set upon it, +before every invokation of any method the filters are processed. Filter +implementations are found in class traversal order, as are the lists of filter +names (each of which is traversed in natural list order). Explicitly invoking +a method used as a filter will cause that method to be invoked twice, once as +a filter and once as a normal method. +.PP +Each filter should decide for itself whether to permit the execution to go +forward to the proper implementation of the method (which it does by invoking +the \fBnext\fR command as filters are inserted into the front of the method +call chain) and is responsible for returning the result of \fBnext\fR. +.PP +Filters are not invoked when processing an invokation of the \fBunknown\fR +method because of a failure to locate a method implementation, or when +invoking either constructors or destructors. +.SH EXAMPLES +.PP +This example demonstrates how to use the \fBnext\fR command to call the +(super)class's implementation of a method. The script: +.CS +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" + \fBnext\fR a {*}$args b + \fBnext\fR pureSynthesis + puts "after chaining from subclass" + } +} +theSubclass create obj +oo::define obj method example args { + puts "per-object method, args = $args" + \fBnext\fR x {*}$args y + \fBnext\fR +} +obj example 1 2 3 +.CE +prints the following: +.CS +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 superclassm args = pureSynthesis +after chaining from subclass +.CE +.PP +This example demonstrates how to build a simple cache class that applies +memoization to all the method calls of the objects it is mixed into, and shows +how it can make a difference to computation times: +.PP +.CS +oo::class create cache { + filter Memoize + method Memoize args { + \fI# Do not filter the core method implementations\fR + if {[lindex [self target] 0] eq "::oo::object"} { + return [\fBnext\fR {*}$args] + } + + \fI# Check if the value is already in the cache\fR + my variable ValueCache + set key [self target],$args + if {[info exist ValueCache($key)]} { + return $ValueCache($key) + } + + \fI# Compute value, insert into cache, and return it\fR + return [set ValueCache($key) [\fBnext\fR {*}$args]] + } + method flushCache {} { + my variable ValueCache + unset ValueCache + \fI# Skip the cacheing\fR + return -level 2 "" + } +} + +oo::object create demo +oo::define demo { + mixin cache + method compute {a b c} { + after 3000 \fI;# Simulate deep thought\fR + return [expr {$a + $b * $c}] + } + method compute2 {a b c} { + after 3000 \fI;# Simulate deep thought\fR + return [expr {$a * $b + $c}] + } +} + +puts [demo compute 1 2 3] \fI\(-> prints "7" after delay\fR +puts [demo compute2 4 5 6] \fI\(-> prints "26" after delay\fR +puts [demo compute 1 2 3] \fI\(-> prints "7" instantly\fR +puts [demo compute2 4 5 6] \fI\(-> prints "26" instantly\fR +puts [demo compute 4 5 6] \fI\(-> prints "34" after delay\fR +puts [demo compute 4 5 6] \fI\(-> prints "34" instantly\fR +puts [demo compute 1 2 3] \fI\(-> prints "7" instantly\fR +demo flushCache +puts [demo compute 1 2 3] \fI\(-> prints "7" after delay\fR +.CE +.SH "SEE ALSO" +oo::class(n), oo::define(n), oo::object(n), self(n) +.SH KEYWORDS +call, method, method chain + +.\" Local variables: +.\" mode: nroff +.\" fill-column: 78 +.\" End: |