output parameters on an abl class event

Posted by jmls on 18-Oct-2011 12:47

It is possible to specify an output or input-output parameter on an event in a class.

This does not seem right - I would have thought that an event is a one-way "lookit, something has happened". Do other languages have this facility ?

However, if I were to use this, and have multiple subscribers to an event, what happens if they each return a different value ? The documentation doesn't quite describe the problem properly

The Publish( ) method passes the same parameters to each event handler subscribed to the event.

Note that any parameter results represent values returned from the last event handler to execute.

However, the order of execution for event handlers is not guaranteed. Therefore, if you subscribe to multiple event handlers,

you cannot be certain what event handler has returned the parameter values from the Publish( ) method.

Right, so order is not guaranteed. However, as the ABL is a single-threaded process, I presume that each subscriber is called, one after the other. So, it leads me to think that the last value returned would be the final result. However, that is not documented. Is it possible that the first value is used, and all other return values ignored ?

I have a requirement where a class needs to get a value from a known method in an unknown class - so I was going to use interfaces and injection (see Peter, see!) . However, this would mean that there could only be one (!) unless I write some form of injection collection.

Urgh. My brain hurts.

All Replies

Posted by whenshaw on 18-Oct-2011 13:02

Julian,

You're correct in thinking that the value(s) returned by the last handler to run is the value you end up with.

.NET, for one, essentially enables you to return values from event handlers by setting properties of objects passed to the handler.

--Wayne

Posted by Admin on 18-Oct-2011 13:12

.NET, for one, essentially enables you to return values from event handlers by setting properties of objects passed to the handler.

I would consider that best practice for the ABL as well.

Posted by jmls on 18-Oct-2011 13:12

There is no way, however, to determine the order, right ?

On 18 October 2011 19:02, Wayne Henshaw

Posted by Peter Judge on 18-Oct-2011 13:17

This does not seem right - I would have thought that an event is a one-way

"lookit, something has happened". Do other languages have this facility ?

My recollection is that this is the same behaviour as for the classic/weakly-typed PUBLISH behaviour.

Wayne said:

.NET, for one, essentially enables you to return values from event handlers

by setting properties of objects passed to the handler.

Wayne beat me to it: use an object and set stuff/properties on it in each subscriber (my answer was more verbose).

Think of the .NET EventArgs stuff in the GUI: you can subscribe multiple event handlers to a single button's Click event, and if you set a property on that, it'll be available as the handlers are executed.

I have a requirement where a class needs to get a value from a known method

in an unknown class - so I was going to use interfaces and injection (see

Peter, see!) . However, this would mean that there could only be one

unless I write some form of injection collection.

"Known method in unknown class" says interfaces to me, so +1 for that

So you'll have a bunch of objects that implement your IKnowThisMethod interface, and also subscribe to a GiveMeTheKnownMethodValue event?

How does the publishing object know which is the right return value? Clearly, this is the programming challenge you're trying to resolve, so what I mean is more in terms of the "business logic" (or whatever). Is it the first responder? The last? Does it matter?

That rule is what you need to establish first, IMO, and then the pattern will follow: whether it's injection or events or something else.

-- peter

Posted by Admin on 18-Oct-2011 13:22

There is no way, however, to determine the order, right ?

Nothing I would rely on.

If order is relevant, create two events.

Posted by jmls on 18-Oct-2011 13:27

I just don't like the idea of undefined behaviour

Subscriber1: return "foo"

Subscriber2: return "bar"

"two men say they're Jesus. One of them must be wrong"

(http://tinyurl.com/6hgj9dv)

Posted by Admin on 18-Oct-2011 13:32

Use two events then.

Posted by jmls on 18-Oct-2011 13:34

What I want to do is to prevent more than one subscriber. I can do this using injection rather than events, so that works for me.

Thanks

Posted by jmls on 18-Oct-2011 13:37

right - that's what I surmised. However, I am somewhat surprised that progress went down the input/output/input-output route for parameters instead of making them input only (allowing an object instance property to be modified, of course)

Posted by jmls on 18-Oct-2011 13:37

I am simply going down the route of last subscriber wins. IOW , the

act of injecting a new handler simply overwrites the previous handler

Posted by jmls on 18-Oct-2011 13:37

poo. What I meant to say is that I am not going to use events, but injection

Posted by Peter Judge on 18-Oct-2011 13:59

jmls wrote:

right - that's what I surmised. However, I am somewhat surprised that progress went down the input/output/input-output route for parameters instead of making them input only (allowing an object instance property to be modified, of course)

I am splitting hairs here, but how is passing a mutable object (ie can be modified) any different  to allowing input-output params? In both cases the order in which the events fire is undefined or undependable-upon (and this seems to be true of other languages, like C# too - http://stackoverflow.com/questions/1645478/order-of-event-handler-execution), and so if you've got some kind of dependency on an  order, then events are not for you. IMO, of course.

-- peter

Posted by jmls on 18-Oct-2011 14:02

they are different because subscriber A's changes to the object are

visible to subscriber B ( or vice-versa depending on order), but an

output parameter is private to each subscriber

Posted by Peter Judge on 18-Oct-2011 14:04

jmls wrote:

What I want to do is to prevent more than one subscriber. I can do this using injection rather than events, so that works for me.

Thanks

So today it's not possible to determine how many subscribers there are to an event (strongly-typed), and as a corrolary, get references to them; you may want to log a bug for this. That way you would be able to figure out if someone else is already subscribed to an event, and unsubscribe them if they are.

Note that this is probably better suited for clean-up than your use-case, but thought I'd put it out there ...

-- peter

This thread is closed