Setting Pdefs

I don’t really understand why the following doesn’t work. I keep running into issues like this when I try to do any complicated sequencing and have parameters change on the fly. Is there a standard way of doing this that I’m missing? Thanks!

(
f = {
	arg test = 1;
	inf.do {
		|i|
		test.postln;
		1.wait;
	};
};
);

z = Pdef(\test1, f); // or just EventPatternProxy(f);
z.play;
z.set(\test, 2);//setting the first time works
z.set(\test, 3);// setting it again does nothing

Afaik Pdef expects that any pattern you place in it will yield Events. And, aside from that, a function passed to Pdef is expected to return a Pattern or Pattern-like object when it is called, which you’re also not doing. A few steps in a few right directions, depending on what you want to achieve…

  1. Tdef is like Pdef, but for any kind of pattern, not just event patterns. The expectation is that the pattern yields wait times (e.g. your 1.wait).
  2. Pdefn is like Pdef but is expected to return single values, not events (it CAN return events, but Pdef has a lot of Event-specific functionality). If ultimately you want to produce e.g. a stream of numeric values, this is the right thing to use.
  3. All of these still expect EITHER a function that returns a pattern/stream, OR a pattern - so, e.g. if you want to use a function with an inf loop, you can wrap it in Prout, which turns a function into a pattern.
Tdef(\test, Prout({
   inf.do {
     |i|
     i.postln;
     1.wait;
   }
})).play;
  1. For the Xdef family of classes, set sets an environment variable that is accessible inside of the Pattern you’re running - it can be a way of passing values into a running pattern from the outside (as you are doing…). However, accessing this environment is a BIT obscure in case of Tdef and Pdefn - it’s passed in as the initial argument to the routine - so something like this would work (e.g. run your loop inside the environment with .use, and access the ~environmentVariable inside:
Tdef(\test, {
    |envir|
    envir.use {
        inf.do {
            ~in.postln;
            1.wait;
        }
    }
}).play;
Tdef(\test).set(\in, "I'm an input");