Func(\symbol) -- Function -- automatic
A global repository of shared functions that may be used for any purpose.
#{ |notes| notes.scramble } => Func(\random);
Func(\random).value([60, 62, 64, 65, 67]);
If there is no function for the given name symbol, nil will be returned.
If needed, you can protect against nil being returned by the function, by appending the adverb protectNil to the chuck operator as below.
The adverb allowNil may be appended to => to override the normal behavior of Func, which is that the first input argument is returned if the function's result is nil.
// A nil return value from this function will be passed back to the user.
{ |a, b| (a < b).if({ a + b }) } => Func(\nilsOK);
// A nil return value will be suppressed, and replaced with the first argument to the function.
{ |a, b| (a < b).if({ a + b }) } =>.protectNil Func(\noNils);
Func(\noNils).value(2, 5);
Func(\noNils).value(5, 2); // result is 5, or 1st input argument
Func(\nilsOK).value(5, 2); // result is nil
Note: Other chucklib storage objects respond to the value message with the object being stored. The object of a Func is a function, and typically what you want to do with a function is execute it. Consequently, Func(name).value evaluates the function and returns the result. If you need to access the function object itself without evaluation, use Func(name).v.
Func and Proto
If you evaluate a Func within a pseudo-method defined in a Proto object, the current environment at the time of running the Func is the Proto. As a result, the Func has full access to the Proto's variables and methods.
Caution: You can really mess up a Proto's state by incorrectly manipulating its variables in a Func.
But, used responsibly, this is a powerful and effective technique. For example, the pbindPreAction of a drum machine process can refer to a Func, which can then set the arrays internal to the process which determine the rhythm, e.g.,
{ var rests;
~amps = ~ampBase.copy;
rests = ~amps.collectIndicesOfItem(0).scramble;
rrand(1, 5).do({ |i|
~amps[rests[i]] = rrand(0.1, 0.4);
});
} => Func(\randSnare);
PR(\bufPerc).chuck(BP(\snare), parms: (
// replace with the path to a real sample, obviously
bufPaths: ["path/to/a/snare-sample.aiff"],
ampBase: #[0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0], // base pattern: beats 2 and 4
amps: 0,
pbindPreAction: \randSnare
));
Thus Func(\randSnare) becomes a generalized way to generate ornamentation for a snare drum, which can be used by any drum machine process. The manipulations to the ~amps array always occur within the process that is currently evaluating, even though the function doesn't have to know about the processes at the time it's saved.