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.function(1);

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);

event.at(\function2).value(foo: 4);
)

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

Regards,
D.

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

hjh

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.)

Best,
Paul

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.addUniqueMethod(\x, 
	{ 
		|a ...args| 
		
		// the first argument will always be the original object
		
		a.class.postln;
		
		// if we only defined ...args, args.first must be this.a
		
		args.printAll
	}
);

// Object.uniqueMethods[a].postln

a.x(*(..6))

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

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; });

a.foo;
b.foo;
c.foo;
d.foo;
)

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