[bug?] arguments.pop() arguments.push() not a function

Roth's icon

When I tried calling pop() and push() on the arguments Array inside an anything() function, Max tells me they are not functions. pop() and push() seem to work as expected in other Arrays. I noticed this problem on Max 5.0.7 and 5.1 on OS X 10.5.8. Here is a bit of JS and a patch demonstrating:

autowatch = 1;

function anything() {
    var a = new Array("a", "b", "c");
    a.pop()
    for (var i in a)
        post(a[i]+"n");
    //post last element in array
    post(arguments[arguments.length-1]+"n");
    //pop off last element
    arguments.pop();
    //print elements in array
    for (var i in arguments)
        post(arguments[i]+"n");
}
Max Patch
Copy patch and select New From Clipboard in Max.

I've thought about this a little more. Is arguments some sort of strange immutable array that allows you to change values, but not size?

Luke Hall's icon

The arguments property is not an array, it just seems a bit like one, its a bit confusing I know. You need to do something like:

var theInput = arrayfromargs(messagename,arguments);

and then you can use array methods like pop() and push() on theInput.

lh

Roth's icon

Interesting, figured it was something like that. Just curious: so what exactly is it. Is this a JavaScript or max feature? Never noticed it in the JavaScript reference.

Luke Hall's icon

It is a feature of javascript itself, have a read here for a bit more information.

lh

Tom Swirly's icon

First, the code sample is a little wonky - it's justvar theInput = arrayfromargs(arguments)
(unless there's something I don't know about arrayfromargs??)

Second, the arguments array is like a stripped down Array that only has indexing and length - the reason is to get rid of the overheard required in creating a new Array every time you make a function call.

It's a necessary workaround for Javascript's lame argument passing (look at Python, much better) but we don't have to love it...

Luke Hall's icon

Ah yes, to avoid confusion I should explain more clearly. The messagename can be used to dynamically process input received using the anything() function. You don't need to use it if you just want the arguments and you have a specific function already declared.

The first example below will output whatever you send to the input. The second example will output the arguments of a "somename" message but not the string "somename" itself.

lh

function anything() {
    outlet(0,arrayfromargs(messagename,arguments));
}

function somename() {
   outlet(0,arrayfromargs(arguments));
}