[Seaside] onAnswer: problems

Avi Bryant avi at beta4.com
Wed Jun 2 05:42:53 CEST 2004


On Jun 1, 2004, at 7:19 PM, Avi Bryant wrote:

> No, you're not doing anything stupid.  It's an artifact of the new way 
> call/answer is implemented; I clearly don't have it quite right yet.  
> #answer: right now signals a WAAnswerNotification, and I'm getting 
> into trouble because the handlers for this are not always what you 
> would expect them to be.  This is the second time today somebody has 
> pointed out a problem with this mechanism - Adrian noticed that 
> sending #answer: to a component other than the one currently 
> processing an action callback didn't work.

To elaborate: these problems, and others, are a result of the following 
decision: that the callbacks of a given component should execute in a 
dynamic scope that matched that component's position in the component 
tree.  That is, if you walked up the stack from within a subcomponent's 
callback, you would find first its decorations, then its parent, then 
its parent's decorations, then its parent's parent, and so on.  The 
advantage of this is that it because this stack can include exception 
handlers, it gives parents very fine grained control over what happens 
in their subcomponents: for example, you could write a decoration that 
caught any validation exceptions in its enclosed components and 
rendered an appropriate error message.  Or you could have filters (like 
those set up by #isolate: and #basicAuthenticateWith:during:) that 
applied only to the callbacks of a specific part of the page, and let 
any others through.  You could also walk the stack to dynamically 
discover your ancestors in the component tree, which is otherwise 
difficult to do.

The problem is that dynamic scope can be a tricky thing to reason 
about, and it's often at odds with our intuition.  For example, the 
block David passed to #onAnswer:, although lexically scoped to the 
parent component ("self" in the block referred to the parent), was 
executed in the dynamic scope of the child, and so was handled in 
unexpected ways.  A similar thing happened when one of Adrian's 
components sent an #answer: message to another - because the current 
dynamic scope was based on the first component, not the receiver of 
#answer:, it didn't work.

So I'm wondering if this is a case of being too clever for my own good. 
  It wouldn't be very hard to go back to the old, "flat" callback 
processing (where all the callbacks are processed directly by the 
render loop, and the components don't get involved at all), which is 
more limited but certainly easier to understand.  Does anyone have any 
strong opinions either way?  Or have I not explained things well enough 
for anyone else to form any? ;)

Avi



More information about the Seaside mailing list