Hi Doug: That is a very useful construct (start,finish) you have abstracted from this wrinkle. This will last for the next decade. init: used to initalize visitor object during construction. start: method called on visitor before traversal. finish: method called on visitor after traversal. return: sets return_val after finish. Please add start/finish to Demeter/Java. -- Karl From dougo@ccs.neu.edu Tue Oct 7 08:21:41 1997 Date: Tue, 7 Oct 1997 08:21:35 -0400 (EDT) From: Doug Orleans To: Karl Lieberherr Cc: dem@ccs.neu.edu Subject: Re: semantics of around By the way, in the use-around example, you have the comment void g_print() to * (PrintVisitor); // should work but does not yet The reason this does not work is that the PrintVisitor constructs its own PrintWriter, which has its own buffer, which never gets flushed. If you add a "*l" to the end of the A class, it will work as expected. This problem is rather tricky to solve. The problem is you don't know when to flush the buffer. I could flush it after every print, but this would be inefficient in several ways (code size, number of function calls, amount of I/O). My best idea is to have yet another kind of visitor method, a "finish" method, which would be called whenever a traversal exits. For symmetry, we could have a "start" method as well (we've discussed this before). Thus the adaptive method: Foo { int f(int arg) to Bar { init (@ /* 1 */ @) start (@ /* 2 */ @) before Bar (@ /* 3 */ @) finish (@ /* 4 */ @) return (@ /* 5 */ @) } } would result in something like this method: Foo { int f(int arg) (@ V v = new Visitor(); /* 1 */ v.set_arg(arg); v.start(); /* 2 */ this.t(v); /* 3 */ v.finish(); /* 4 */ return v.get_return_val(); /* 5 */ @) traversal t(V) { to Bar; } } Then a PrintVisitor would have finish (@ out.flush(); @) What do you think? --Doug