Menu

#456 [manual] A signal should be created *after* the objects that are listening to it

v1.0 (example)
closed-fixed
nobody
manual (41)
5
2018-12-29
2017-08-20
Evan Aad
No

The description of class signal in the chapter on object-oriented programming (chapter 93) says:

once an object has been connect to a signal, it will continue to receive emissions of this signal till the end of the life-time of the signal. This is even true when the object no longer exists (but the signal does), so care must be taken that signal objects are always created before the objects that are listening to them.

Shouldn't the admonition in the last sentence be:

so care must be taken that signal objects are always created after the objects that are listening to them?

in order to avoid a situation that a signal is sent to an object that no longer exists?

To illustrate the problems that can arise if the admonition currently written in the manual is heeded, consider the following plain TeX manuscript:

\input pgf.tex\relax%
\usepgfmodule{oo}%
\pgfooclass{A}{\method m(){In class A.}}%
\pgfooclass{B}{\method m(){In class B.}}%
\pgfoonew\sig=new signal()%
\begingroup
    \pgfoonew \a =new A()%
    \sig.connect(\a,m)%
\endgroup
%\pgfoonew \b =new B()%
\sig.emit()%
\bye

In the manuscript, the signal object \sig is created before the object, \a, that is listening to it, however when the signal's \emit method is invoked, \a has gone out of scope and no longer exists. Therefore, the following error is reported:

! Missing \endcsname inserted.
<to be read again> 
                   \pgfooX2@class 
\pgfoo@caller ...\csname pgfooX#1@class\endcsname 
                                                  .#2\endcsname \ifx \pgfoo@...

\pgfoo@signal@call ...ndafter (\pgfoo@signal@args 
                                                  )
\pgfoo@caller@temp ... {#1}\pgfoovalueof {emitter}

<to be read again> 
                   \pgfoothis@count 
<inserted text> 
                0
...
l.11 \sig.emit()
                %

A much worse scenario occurs if the line that was commented-out in the example manuscript is un-commented to make it active. In this case, the manuscript compiles successfully, but the method that gets called doesn't belong to the object that registered, but rather to a different object, \b, that doesn't even have the same class as \a and that didn't even exist when \a registered to the signal! The output in this case is:

In class B.

Discussion

  • Stefan Pinnow

    Stefan Pinnow - 2018-12-29

    Good catch. Thank you for reporting. This is fixed now.

     
  • Stefan Pinnow

    Stefan Pinnow - 2018-12-29
    • status: open --> closed-fixed