In an effort to simulate a package behavior, I often load a file into
a Script and then exec() it against a new empty scope (parented to the
global scope). The script calls a function called 'package' provided
by the new object to declare its name, and then afterwards I install
it into the global scope under that name. This has been working very
well but I have bumped into a really nasty difference between compiler
and interpreter lately and I cannot figure it out.

For whatever reason, when I load packages in this fashion the package
scope is always visible to the functions in the package, i.e. I can
always see 'package-level' variables and functions, no matter what
scope I am actually running in. I don't exactly understand this
behavior, but it is what I want so I won't complain. However, when
using the compiler instead of the interpreter this sometimes fails to
happen, if and only if there is a function in the 'package' that calls
another function in the package. I don't even need to call the
function to cause it to break, just define it.

So I can have

-- file1.js --

package('my.file1.package');
load('file2.js');

my.file2.package.foo();

-- file2.js --

package('my.file2.package');

let packageVariable = 0;

function foo() { packageVariable++; }

And it works just fine. However, if I add the following lines to the
bottom of file2.js

function bar() { baz(); }
function baz() {}

then it breaks with a "can't find packageVariable" type of error.

The code that loads the 'package' looks like this:

    public Script loadPackage(File path, Context cx) throws
FileNotFoundException, IOException {
        Package newPackage = new Package(runtime.getGlobalScope());
        newPackage.setParentScope(runtime.getGlobalScope());
        File f = locateScript(path);

        // check if we've already loaded this package, we don't need
to load it again
        if(null != packages.get(f.toString())) {
            return null;
        }

        // load the script and execute it into the new package
        Script s = loadScript(f, cx);
        s.exec(cx, newPackage);
        packages.put(f.toString(), newPackage);
        installPackage(newPackage);
        return s;
    }

Please let me know if anyone can help with this.

Thanks,
Ben Reesman
_______________________________________________
dev-tech-js-engine-rhino mailing list
[email protected]
https://lists.mozilla.org/listinfo/dev-tech-js-engine-rhino

Reply via email to