Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement doesNotUnderstandWithKeys #6227

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
318f139
First commit.
Mar 2, 2024
591e8f6
Format
Mar 2, 2024
b30607d
Format again
Mar 2, 2024
4e77318
Format again again
Mar 2, 2024
b336225
Provide better interface for redirecting function calls
Mar 3, 2024
389c8d3
Comment and refactor code
Mar 4, 2024
958af68
Documentation and small renaming of arg
Mar 4, 2024
be80f55
Remove helper methods from object, and delegate to Object, Function, …
Mar 9, 2024
ec776bc
Update Tuning*doesNotUnderstandWithKeys
Mar 9, 2024
a8fafc1
Renaming and formatting.
Mar 10, 2024
2154969
Remove evaluateWith* methods, simplify the argument creation, update …
Mar 11, 2024
faf6b29
Formatting.
Mar 11, 2024
6d6a86f
Simplify how callable arguments are made.
Mar 12, 2024
d9f07f2
Implement performWith and valueWith
Mar 13, 2024
750f8f5
Remove reformatting.
Mar 13, 2024
61b2c68
Remove reformatting.
Mar 13, 2024
4144747
Move the creation of the argument array to FunctionDef so it can be u…
Mar 13, 2024
32c3333
Update Scale and Tuning
Mar 13, 2024
919956f
Given Object a default value with and fix commit syn issue.
Mar 13, 2024
9dc1da5
Remove VarArgs on performWith
Mar 13, 2024
26428b3
Missed bracket from commit
Mar 13, 2024
aa519f4
Simply Scale's doesNotUnderstandWithKeys
Mar 13, 2024
ab00109
Rename defaultArguments to defaultArgs
Mar 13, 2024
ad04f69
Docs and a comment
Mar 13, 2024
aeb6a95
Docs remove old method
Mar 13, 2024
b3f7a7f
Simply some logic in makePerformableArray
Mar 13, 2024
ebf5805
Actually undo mistaken formatting. Fixed comments. Simplify code.
Mar 14, 2024
f79e656
Depreciate functionPerformList in favour of functionPerformWith
Mar 14, 2024
27679c5
Docs
Mar 14, 2024
704d0cf
Remove indents
Mar 14, 2024
d15afc8
Comment grammar
Mar 14, 2024
76b7708
Reinstate functionPerformList
Mar 14, 2024
024eac1
Reinstate functionPerformList
Mar 14, 2024
0b15f0f
Reinstate functionPerformList
Mar 14, 2024
b38cb22
Reinstate functionPerformList
Mar 14, 2024
ad8f2cb
Formatting, small optimization.
Mar 14, 2024
629686c
Remove default args of valueWith
Mar 17, 2024
d0b8df2
Tidy, rename, lots of docs.
Mar 20, 2024
7826824
Docs parens, undo sc formatting.
Mar 20, 2024
ef4fdc3
Remove semi-colons, Docs typo
Mar 21, 2024
bf55260
Typo and spaces/tabs
Apr 15, 2024
94a6cd2
Typo and spaces/tabs
Apr 15, 2024
5e4a7f8
Undo auto indent.
Apr 15, 2024
eda146e
Remove DoesNotUnderstandWithKeysError
Apr 15, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
57 changes: 56 additions & 1 deletion HelpSource/Classes/Function.schelp
Expand Up @@ -122,10 +122,65 @@ e = Environment.make({ ~a = 3; ~b = 10 });
)
::

method::valueWith
Evaluate the function using a mix of arguments and keyword arguments.

Errors are thrown if: the arguments collide, an unknown keyword is found, or there are too many arguments.
See link::Classes/FunctionDef#-makePerformableArray:: for a detailed description.

argument::argumentsArray
Arguments as an array.

argument::keywordArgumentPairs
Keyword arguments as any link::Reference/Key-Value-Pairs:: structure.


discussion::
code::
(
f = { |a, b ...e|
a.debug(\a);
b.debug(\b);
e.debug(\e);
};
f.valueWith([\a], (e: [1,2,3]));
)
::


method::functionPerformList

For Function, this behaves the same as valueArray(arglist). It is used where Functions and other objects should behave differently to value, such as in the object prototyping implementation of Environment.
For Function, this behaves the same as valueArray(arglist).
It is used where Functions and other objects should behave differently to value,
such as in the object prototyping implementation of Environment.

Ensure both this method and link::#-functionPerformWith:: do the same thing or the behaviour will change when the user passes keyword arguments.

argument::selector
The message to be run as a link::Classes/Symbol::.

argument::arglist
The arguments to pass as an link::Classes/Array::.

method::functionPerformWith

For Function, this behaves the same as valueArray(arglist).
It is used where Functions and other objects should behave differently to value,
such as in the object prototyping implementation of Environment.

Ensure both this method and link::#-functionPerformList:: do the same thing or the behaviour will change when the user passes keyword arguments.

Errors are thrown if: the arguments collide, an unknown keyword is found, or there are too many arguments.
See link::Classes/Method#-makePerformableArray:: or link::Classes/FunctionDef#-makePerformableArray:: for a detailed description.

argument::selector
The message to be run as a link::Classes/Symbol::.

argument::argumentsArray
Arguments as an link::Classes/Array::.

argument::keywordArgumentPairs
Keyword arguments as any link::Reference/Key-Value-Pairs:: structure.

method::performWithEnvir

Expand Down
66 changes: 62 additions & 4 deletions HelpSource/Classes/FunctionDef.schelp
Expand Up @@ -30,7 +30,7 @@ code::

method::sourceCode

Get the source code string.
Get the source code as a link::Classes/String::.
code::
{ |a = 9, b = 10, c| a + b }.def.sourceCode.postcs;
::
Expand All @@ -45,18 +45,29 @@ return a list of all references to a given symbol.

method::argNames

Get the Array of Symbols of the argument names.
Get all of the arguments' names as a link::Classes/SymbolArray::.

code::
{ |a = 9, b = 10, c| a + b }.def.argNames;
::
method::prototypeFrame

Get the array of default values for argument and temporary variables.
method::argumentNamesForCall
Returns the argument names as needed for calling the function as an link::Classes/Array::.
This will remove any internal arguments.

method::prototypeFrame
Get an link::Classes/Array:: of default values for all arguments and variables.

code::
{ |a = 9, b = 10, c| a + b }.def.prototypeFrame;
{ |a = 9, b = 10, c| var i = 'I\'m stored here too!'; a + b }.def.prototypeFrame;

::

method::defaultArgs
Returns the default arguments supplied in place of those not specified in a function call, if no default was provided for an argument, then link::Classes/Nil:: is returned in its place.


method::varNames

Get the Array of Symbols of the local variable names.
Expand Down Expand Up @@ -110,6 +121,53 @@ code::
{ |a = 9, b = 10, c| a + b }.def.makeEnvirFromArgs;
::

method::makePerformableArray

This is used internally by link::Classes/Function#-valueWith:: which is sufficient for all uses and recommended over link::#-makePerformableArray::.

Returns an array that can be passed directly to link::Classes/Function#-valueArray::.

Both keyword and non-keyword arguments may be provided at the same time.

Errors are thrown if: a value for an argument is present in both the code::argumentsArray:: and the code::keywordArgumentPairs:: (argument collision),
if a keyword argument's name cannot be found (unknown keyword),
and if too many arguments are given to code::argumentsArray:: (too many arguments).

Variable arguments are best placed with a keyword argument.
However, if the code::keywordArgumentPairs:: is empty and all arguments in the code::argumentsArray:: are present, any extra arguments in code::argumentsArray:: will be passed to the variable argument, if present.
Please note, that variable arguments are unpacked and individually appened to the end of the array, not contained in their own array.


argument::argumentsArray
Arguments as an link::Classes/Array::.

argument::keywordArgumentPairs
Keyword arguments as any link::Reference/Key-Value-Pairs:: structure.

returns::Arguments as an link::Classes/Array::.

JordanHendersonMusic marked this conversation as resolved.
Show resolved Hide resolved
discussion::
code::
(
f = { |a b ...e|
var i = 0;
a.debug(\a);
b.debug(\b);
e.debug(\e);
};
)

// using makePerformableArray, not recommended
(
var args = f.def.makePerformableArray([\a], (e: [1,2,3]));
f.valueArray(args);
)

// using valueWith, recommended
f.valueWith([\a], (e: [1,2,3]));
::


subsection::Generating Strings

method::makeFuncModifierString
Expand Down
66 changes: 63 additions & 3 deletions HelpSource/Classes/Method.schelp
Expand Up @@ -4,7 +4,10 @@ summary:: Code that implements an operation upon instances of a Class.
related:: Classes/Class

description::
A Method is code that is a part of the set of operations upon instances of a link::Classes/Class::.
link::Classes/Method::s are created for each method defined with a class.

For a definition of a method,
see link::Guides/Intro-to-Objects:: and link::Guides/WritingClasses::.

subsection:: Related Keywords

Expand Down Expand Up @@ -39,17 +42,74 @@ instanceMethods::

method::ownerClass
returns::
The link::Classes/Class:: for which the method is part of the implementation.
If the receiver is an instance method, the owner class is the class for this instance.
For a class method, it is the class of the class, whose name is prefixed with "Meta_".

code::
m = Array.findRespondingMethodFor('reverse');
m.ownerClass; // Array
m = Array.class.findRespondingMethodFor(\new);
m.ownerClass; // Meta_Array
::

method::name
returns::
A link::Classes/Symbol:: which is the name of the Method.

method::primitiveName
returns::
A link::Classes/Symbol:: which contains the name of the primitive function that implements the Method, if there is one.
A link::Classes/Symbol:: which contains the name of the primitive function that implements the Method,
if there is one, otherwise returns link::Classes/Nil::.

method::argumentNamesForCall
Returns the argument names as needed for calling the function as an link::Classes/Array::.
This will remove any internal arguments include 'this'.

method:: filenameSymbol
returns::
A link::Classes/Symbol:: which is the full path of the source file that this method is defined in.

method::makePerformableArray
This is used internally by link::Classes/Object#-performWith:: which is sufficient for all uses and recommended over link::#-makePerformableArray::.

Returns an array that can be passed to link::Classes/Object#-performList:: along with the selector.

Both keyword and non-keyword arguments may be provided at the same time.

Errors are thrown if: a value for an argument is present in both the code::argumentsArray:: and the code::keywordArgumentPairs:: (argument collision),
if a keyword argument's name cannot be found (unknown keyword),
and if too many arguments are given to code::argumentsArray:: (too many arguments).

Variable arguments are best placed with a keyword argument.
However, if the code::keywordArgumentPairs:: is empty and all arguments in the code::argumentsArray:: are present, any extra arguments in code::argumentsArray:: will be passed to the variable argument, if present.
Please note, that variable arguments are unpacked and individually appened to the end of the array, not contained in their own array.


argument::argumentsArray
Arguments as an link::Classes/Array::.

argument::keywordArgumentPairs
Keyword arguments as any link::Reference/Key-Value-Pairs:: structure.

returns::Arguments as an link::Classes/Array::.

discussion::
code::
a = "meow MEOW woof bahh bahh Meow";

// how a user might call a method
a.findAll("meow", ignoreCase: true);


// using makePerformableArray directly, not recommended
(
var args = String
.findRespondingMethodFor('findAll')
.makePerformableArray(["meow"], [ignoreCase: true]);

a.performList('findAll', args);
)

// using performWith, recommended
a.performWith('findAll', ["meow"], [ignoreCase: true]);
::
81 changes: 78 additions & 3 deletions HelpSource/Classes/Object.schelp
Expand Up @@ -470,7 +470,7 @@ Instead of directly sending a method to an object, a method may be invoked given

method::perform

The selector argument must be a Symbol. Sends the method named by the selector with the given arguments to the receiver.
The selector argument must be a link::Classes/Symbol::. Sends the method named by the selector with the given arguments to the receiver.

If the first argument is an Array or List, this method behaves like code::performMsg::. However, this usage is discouraged, and code::performMsg:: ought to be used instead.

Expand All @@ -495,7 +495,7 @@ a.performMsg([\value, 1, 2, 3]);
method::performWithEnvir

argument:: selector
A Symbol representing a method selector.
A link::Classes/Symbol:: representing a method selector.
argument:: envir
The remaining arguments derived from the environment and passed as arguments to the method named by the selector.
discussion::
Expand All @@ -507,7 +507,7 @@ a.performWithEnvir(\value, (a: 1, c: 3, d: 4, b: 2));
method::performKeyValuePairs

argument:: selector
A Symbol representing a method selector.
A link::Classes/Symbol:: representing a method selector.
argument:: pairs
Array or List with key-value pairs.
discussion::
Expand All @@ -516,6 +516,42 @@ a = { |a, b, c| postf("% plus % plus % is %\n", a, b, c, a + b + c); "" };
a.performKeyValuePairs(\value, [\a, 1, \b, 2, \c, 3, \d, 4]);
::

method::performWith
Evaluate a method using a mix of arguments and keyword arguments.

Errors are thrown if: the arguments collide, an unknown keyword is found, or there are too many arguments.
See link::Classes/Method#-makePerformableArray:: for a detailed description.

argument:: selector
A link::Classes/Symbol:: representing a method selector.

argument::argumentsArray
Arguments as an link::Classes/Array::.

argument::keywordArgumentPairs
Keyword arguments as any link::Reference/Key-Value-Pairs:: structure.

discussion::
code::
7819.performWith(\asTimeString, [0.1, 365], (decimalPlaces:4));

{ SinOsc.ar }.performWith(\plot, [0.05], (minval:0, maxval:1));

"meow MEOW woof bahh bahh Meow".performWith('findAll', ["meow"], [ignoreCase: true]);

// calling value on function shows how arguments are assigned:
(
f = { |a, b ...e|
JordanHendersonMusic marked this conversation as resolved.
Show resolved Hide resolved
a.debug(\a);
b.debug(\b);
e.debug(\e);
};

f.performWith(\value, [\a], (e: [1,2,3]));
)
::
However, when calling a link::Classes/Function:: it is best to use link::Classes/Function#-valueWith::.

method::tryPerform

Like 'perform', but tryPerform passes the method to the receiver only if the receiver understands the method name. If the receiver doesn't implement that method, the result is nil. Note that this does not catch errors like 'try' does (see Exception). If the receiver does have a matching method but that method throws an error, execution will halt. But, 'tryPerform' is faster than 'try'.
Expand All @@ -530,6 +566,12 @@ Set[1, 2, 3].tryPerform(\keysValuesDo, { |key, value| [key, value].postln });
(a: 1, b: 2, c: 3).tryPerform(\keysValuesDo, { |key, value| [key, value].flippityblargh });
::

method::functionPerformList
A method called in object prototyping, see link::Classes/IdentityDictionary#-new::.
By default this will do nothing and return the object.
link::Classes/Function#-functionPerformList:: provides a useful implementation.
Not called in normal use.
JordanHendersonMusic marked this conversation as resolved.
Show resolved Hide resolved

method::superPerform

Like perform, superPerform calls a method, however it calls the method on the superclass.
Expand Down Expand Up @@ -652,6 +694,39 @@ foo {
}
::


method::doesNotUnderstand
This is called when an object receives a message it does not understand.
Object's implementation will throw an error, but other classes (link::Classes/IdentityDictionary::) might override this.

argument::selector
The name of the message as a link::Classes/Symbol::.

argument::... args
The arguments passed.

code::
4.someThing(2) // ERROR: Message 'someThing' not understood.
::

method::doesNotUnderstandWithKeys
This is called when an object receives a message it does not understand and there are keyword arguments.
Object's implementation will throw an error, but other classes (link::Classes/IdentityDictionary::) might override this.

argument::selector
The name of the message as a link::Classes/Symbol::.

argument::argumentsArray
An link::Classes/Array:: of arguments that have been passed directly and not via keywords.

argument::keywordArgumentPairs
The arguments that have been passed via keywords.
These are formatted as an link::Classes/Array:: of key-value pairs link::Reference/Key-Value-Pairs::.

JordanHendersonMusic marked this conversation as resolved.
Show resolved Hide resolved
code::
4.someThing(3, someArgument: 42) // ERROR: Message 'someThing' not understood.
::

subsection::Printing and Introspection

method::post
Expand Down