[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Object.Attach silently does nothing for a plain observer class
[Thread Prev] | [Thread Next]
- Subject: Object.Attach silently does nothing for a plain observer class
- From: Alarch <alarch@xxxxxxxxx>
- Date: Wed, 9 Sep 2026 11:00:38 +0200
- To: <user@xxxxxxxxxxxxxxxxxxxxxx>
Dear Benoît, dear all,
A separate report from my other message about GB_BASE (keeping one topic
per mail) - another gotcha from the same small llhttp-based HTTP server
proof-of-concept, this time on the Gambas language side rather than the
native-component side.
I wanted a small custom class (one instance per accepted connection) to
receive both a Socket's "Read" event and my own component's custom event,
so I used:
Object.Attach(Me, hSocket, "Socket")
Object.Attach(Me, hParser, "Parser")
expecting Socket_Read and Parser_MessageComplete to fire on Me. Neither
ever did: no compile error, no runtime error, the events just silently
never arrived. gbc3 accepts it, gbr3 runs it, and it looks completely
correct by reading the method's own signature (Object, Parent, Name).
Digging into main/gbx/gbx_object.c, OBJECT_attach() explains why:
if (!class->is_observer && class->n_event == 0)
return;
"class" here is the first argument's own class (the would-be observer,
"Me" in my case). Unless that class is the built-in Observer class, or
declares at least one Event of its own, the call is a silent no-op.
A plain hand-written .class with ordinary Public Sub methods and no Event
statement satisfies neither condition, so it can never actually receive
anything through Object.Attach, regardless of what it's trying to attach
to.
Two ways I found to actually get what I wanted, once I understood this:
1. For a native class already marked _IsControl/_IsVirtual (Socket,
ServerSocket, DnsClient, ...): these already auto-route their own
events to whatever module/class created or holds them, matched purely
by class name (Socket_Read, not an attached custom name), with Last
identifying which specific instance raised the event - exactly the
pattern used in the official Networking/ServerSocket example, which
does not use Object.Attach anywhere. I'd somehow missed that this
auto-routing existed and jumped straight to Object.Attach as "the"
generic way to observe an object.
2. For my own component's event, which happened to be raised synchronously
from a method I call myself anyway: I just dropped the event and
exposed a plain boolean property instead, checked right after the call.
No attachment mechanism needed at all in that case.
Question/suggestion, now that I understand the "why": would it be
reasonable for Object.Attach to raise an error when given an observer that
doesn't satisfy is_observer/n_event>0, instead of silently doing nothing?
From the method's own signature there is no hint that the first argument
has this restriction, so I suspect I won't be the last person to lose time
to this. Happy to test a patch or help however's useful if this is
considered worth changing.
Best regards,
--
Marc
| Re: Object.Attach silently does nothing for a plain observer class | Benoît Minisini <benoit.minisini@xxxxxxxxxxxxxxxx> |