It’s because Pdef in general chains its envir
as an event before the source
. So “by design”, because the envir is meant to be editable by gui with sliders, as long as it’s an actual Dictionary or sub-class thereof. (You can replace the whole envir with a Pbind for example, but that will lose such gui-editing features… and there’s little point in doing that since you chain Pdefs too.)
Think of the envir
as the (gui-editable) data and the source
of the Pdef as the program code that operates on that. This is a bit different “philosophy” than Pbind where everything (code and data) is “mixed together” and it’s up to you to separate it, if you want that. (You can’t gui a Pbind though.)
I just happened to post an example to another question showing the Pdef philosophy of what to put where.
As far internals go, effectively (although I’ve changed the var names a bit in the first method–there are more intermediates in the actual code.)
EventPatternProxy : TaskProxy {
source_ { arg pattern;
//...
envir !? { pattern = pattern <> envir };
//...
source = pattern
}
envir_ { arg dict;
envir = dict;
this.source = source;
}
}
And set
is inherited way back from PatternProxy, doing the obvious thing:
PatternProxy : Pattern {
set { arg ... args;
if(envir.isNil) { this.envir = this.class.event };
args.pairsDo { arg key, val; envir.put(key, val) };
this.changed(\set, args);
}
}