.set method to ALL instances of an array?

Hi folks!
A simple beginner question: I have an array (~synths) with 10 instances of a synth. I need to send to all of them the same message. How can I send a .set message to ALL the instances of an array?
I have tried this:

~synths.set(\freq, 100);

but I get an error message (“Message “set” not understood”). Ok, I’m a beginner so I’ve clearly used a wrong syntax.
Then I’ve tried this:

~synths[0, 1, 2, 3, 4, 5, 6, 7, 8, 9].set(\freq, 100);

but only the latest allocated instance actually changed its frequency according to my message. Nothing happens to the others.
This seems the only functioning method:

~synths[0].set(\freq, 100);
~synths[1].set(\freq, 100);
~synths[2].set(\freq, 100);
~synths[3].set(\freq, 100);
//...and so on

but it seems quite long to me, there should be a smarter way to do that!
Can someone help me?
Thanks you all!
A.

Hi,

// Have a look at the Array, ArrayedCollection, Collection and SequenceableCollection help files.

~synths.do(_.set(\freq, 100)); // partial application, short for:

~synths.do { |x| x.set(\freq, 100) };


// or: put all Synths into a Group g, then you can do

g.set(\freq, 100)

It works! I’ll take a look at Group too.
Thanks a lot!

Just adding the obvious conceptual difference between do and Group: with Group you can only set all nodes to the same value, while with do you can set different values for each node

2 Likes

Slightly longer explanation: some methods get automatically “spread” to array (or collection) items and some (in fact, most) do not. The exact list depends on the collection, but most use the one from SequenceableCollection. set is alas not among the methods that receive this “automagic” treatment.

But besides passing your own “action” function to Collection do and collect, you can also convince the collection apply any selector to its members, albeit this is a bit longer to write:

[1, 2, 3].neg

is just “automagically” doing

[1, 2, 3].performUnaryOp(\neg)

There are similarly binary and n-ary ops. Since set needs 2 args beside the receiver, it’s of the n-ary version. Alas the method for this n-ary op application has a somewhat unintuitive name for SequenceableCollection, multiChannelPerform. As an example of calling it, here I’m using Pdefs as targets, which also have a set method, since it’s easier to show the result

[Pdef(\a), Pdef(\b)].multiChannelPerform(\set, \freq, 100)

Pdef(\a).envir // -> ( 'freq': 100 )
Pdef(\b).envir // -> ( 'freq': 100 )

And yeah, that’s exactly the same same as calling do with the appropriate function as arg

[Pdef(\a), Pdef(\b)].do(_.set(\freq, 100))