Page 1 of 1

script function not recognized

Posted: Wed Mar 09, 2011 8:29 pm
by Commander McLane
I guess I am being stoopid here, but I can't see it.

I thought I had the syntax for forEach copied faithfully from somewhere else, but there is obviously a bug somewhere.

This code:

Code: Select all

        ...
        var amnestyReservists = system.addShips("pirate", 3, [0, 0, 0], 15000);
        amnestyReservists.forEach(function(ship){
            this.$prepareAmnestyReservist(ship);
            ship.switchAI("anarchiesAmnestyReservistAI.plist");
        });
        ...

this.$prepareAmnestyReservist = function(ship)
{
    // doing stuff
}
gives me this exception in the third line:

Code: Select all

Exception: TypeError: this.$prepareAmnestyReservist is not a function
    Active script: Anarchies 2.4
    anarchies.js, line 104:
                this.$prepareAmnestyReservist(ship);
Why?

Re: script function not recognized

Posted: Wed Mar 09, 2011 8:44 pm
by JensAyton
Because you haven’t specified the optional thisObject parameter, so this is the global object. (If you were using strict mode, as you should, it would be undefined.)

Re: script function not recognized

Posted: Wed Mar 09, 2011 8:54 pm
by Commander McLane
So should it be

Code: Select all

        amnestyReservists.forEach(function(ship){
            this.$prepareAmnestyReservist(ship);
            ship.switchAI("anarchiesAmnestyReservistAI.plist");
        }, worldScripts.Anarchies);
?

I hope I have understood that.

So the way forEach works has changed with the new JS engine (I don't remember to have used the thisObject parameter before).

Probably that means that I may have to go hunting for other instances of using it in my other OXPs.


Oh, and while we're at it: I wasn't paying full attention during your explanations about the transition to the new JS engine (sorry), so I don't really know what strict mode is all about, and why I should use it, and how I would. Which topic do I find the explanation in?

Re: script function not recognized

Posted: Wed Mar 09, 2011 9:06 pm
by JensAyton
Commander McLane wrote:
So should it be

Code: Select all

        amnestyReservists.forEach(function(ship){
            this.$prepareAmnestyReservist(ship);
            ship.switchAI("anarchiesAmnestyReservistAI.plist");
        }, worldScripts.Anarchies);
?

I hope I have understood that.
You could just use this.
Commander McLane wrote:
So the way forEach works has changed with the new JS engine (I don't remember to have used the thisObject parameter before).
You’re misremembering. this is never inherited by inner functions.
Commander McLane wrote:
Oh, and while we're at it: I wasn't paying full attention during your explanations about the transition to the new JS engine (sorry), so I don't really know what strict mode is all about, and why I should use it, and how I would. Which topic do I find the explanation in?
I think I covered it elsewhere, but in the 1.75 announcement I linked to this page and recommended all OXPs use it. The short version is, it helps catch bugs by generating errors for certain types of buggy situation instead of glossing over them, and removes some advanced language features that you almost certainly haven’t seen. Some of those errors were warnings in earlier versions of Oolite, but are now ignored by default if you don’t opt in to strict mode.

Re: script function not recognized

Posted: Wed Mar 09, 2011 9:12 pm
by Commander McLane
Ahruman wrote:
Commander McLane wrote:
So the way forEach works has changed with the new JS engine (I don't remember to have used the thisObject parameter before).
You’re misremembering. this is never inherited by inner functions.
More probably I haven't used it yet in this way. Your ur-example which I have been copying ever since sits here.
system.allShips.forEach(function (ship) { ship.remove() })
No thisObject parameter, but also no use of this inside the function, which I guess means that the optional parameter is superfluous in this case.