How to pass arguments by name when calling an Object Prototype 'method'?

This is mostly a syntax issue, so no real problem, but I find very convenient to call an Event key using ().something instead of ().at(\something), and more precisely instead of ().at(\something).value() in the case the value is a function.

However, I’d like to reference this function arguments by names, so that it can be specified easily by the programmer. But when using the first syntax, it doesn’t work :

var event = ();

event.function = { arg self, foo = 0; foo.postln };

event.function2 = { arg self, foo = 0; foo.postln };
event.function2(foo: 2);

event.function3 = { arg self, foo = 0; foo.postln };
event.function3.value(foo: 3);\function2).value(foo: 4);

Am I missing something or is it problematic to use the event.function2(foo: 2); syntax, which I find elegant ?


As far as I know, this isn’t supported because it isn’t directly calling the function.


You can work around it by using double brackets - a function inside a function, so event.function returns the inner function.

var event = ();
event.function = {{ arg foo = 0; foo.postln }};
event.function.value(foo: 3);
// -> 3

(edit: I removed the self argument in the function as it is not relevant here.)


1 Like

Good ! Thank you very much for this, I would never have guessed this double enclosure tip.

With syntax shortcut, we’re almost at the expected result :

event.function.(foo: 3);

Any object can be defined with unique method behavior, excluding events which conflict over prototyping.

a = []; 

// Object.uniqueMethods.printAll

		|a ...args| 
		// the first argument will always be the original object
		// if we only defined ...args, args.first must be this.a

// Object.uniqueMethods[a].postln


// Object.uniqueMethods[a][\x].cs

Well, that’s indeed true. Seeing both answers above, I can indeed end up with those two method calls working perfectly :

event.function.(foo: 3);
event.function(foo: 3);

I never studied computer programming and those things are confusing me. Somehow I think the correct answer would be that if you intend to store a Function as a value in a Dictionary, then you should instead create an Object.

Sorry for the double post, but after investigating, previous statement is false : you can’t call .addUniqueMethod on Environment and IdentityDictionary classes :

var a = Event().addUniqueMethod(\foo, { |self| "foo".postln; });
var b = Environment().addUniqueMethod(\foo, { |self| "foo".postln; });
var c = Dictionary().addUniqueMethod(\foo, { |self| "foo".postln; });
var d = IdentityDictionary().addUniqueMethod(\foo, { |self| "foo".postln; });;;;;

Considering inheritance, it’s strange that Dictionary actually responds correctly to this method.