It appears that in Rhino, doing "myvar = undefined" is the same as doing EngineBindings.remove(myvar), however in Nashorn the EngineBindings.remove() operation behaves quite differently.

I've attached a Jython program that I've run under jdk7 and jdk8 that point up the differences (in /RED italics/):

     JAVA 7 (RHINO) JAVA 8 (NASHORN)

Case 1: No longer able to store a value after Bindings.remove().
+----Expr "myvar = 33" +----Expr "myvar = 33"

  myvar = 33                              myvar = 33
  Bindings.remove(myvar)                  Bindings.remove(myvar)
    Engine.eval('myvar'): FAILED            Engine.eval('myvar'): FAILED
    typeof(myvar)=undefined typeof(myvar)=undefined
    myvar in bindings: False                myvar in bindings: False
  myvar = 33                              myvar = 33
/Engine.eval('myvar'): 33                Engine.eval('myvar'): FAILED//
//    typeof(myvar)=number typeof(myvar)=undefined//
//    myvar in bindings: True                 myvar in bindings: False/

Case 2: Bindings.remove() does not remove the value.
+----Expr "var myvar=33" +----Expr "var myvar=33"

  var myvar=33                            var myvar=33
Bindings.remove(myvar) Bindings.remove(myvar)
/Engine.eval('myvar'): FAILED Engine.eval('myvar'): 33//
//    typeof(myvar)=undefined typeof(myvar)=number//
//    myvar in bindings: False                myvar in bindings: True/
  var myvar=33                            var myvar=33
    Engine.eval('myvar'): 33                Engine.eval('myvar'): 33
    typeof(myvar)=number                    typeof(myvar)=number
    myvar in bindings: True                 myvar in bindings: True

We previously used Bindings.remove('myvar') and could not understand Nashorn's behavior. We've switched to using "myvar = undefined" and everything seems fine now.

Nonetheless, can someone explain why doing Bindings.remove("var") shows this behavior?

Thank you,
Eric Woudenberg

# Investigate the funny behavior of remove

from javax.script import ScriptEngineManager, ScriptContext

#from java.lang import System
#System.setProperty('nashorn.args','--global-per-engine')

def show(ref):
    try:
        print "    Engine.eval('%s'):" % ref, Engine.eval('%s' % ref) 
    except:
        print "FAILED"
    print '    typeof(%s)=%s' % (ref, Engine.eval('typeof(%s)' % ref))
    print '    myvar in bindings:', 'myvar' in Bindings

def run_setundefined(expr, ref):
    print '\n  %s' % expr
    Engine.eval(expr, Bindings)

    Engine.eval('%s=undefined' % ref)
    print "  %s=undefined" % ref
    show(ref)

    Engine.eval(expr, Bindings)
    print '  %s' % expr
    show(ref)
    
def run_removebinding(expr, ref):
    print '\n  %s' % expr
    Engine.eval(expr, Bindings)
    #show(ref)

    Bindings.remove(ref)
    print "  Bindings.remove(%s)" % ref
    show(ref)

    Engine.eval(expr, Bindings)
    print '  %s' % expr
    show(ref)
    
def main():
    global Engine, Bindings
    Engine = ScriptEngineManager().getEngineByName("JavaScript")

    ref =  'myvar'
    sequence = 'myvar = 33', 'var myvar=33', 'this.myvar = 33'
    print '********** using Bindings.remove(myvar) **********'
    for expr in sequence:
        Bindings = Engine.createBindings()
        Engine.setBindings(Bindings, ScriptContext.ENGINE_SCOPE)
        print '\n+----Expr "%s"' % expr
        run_removebinding(expr, ref)

    print '\n********** using "myvar = undefined" **********'
    for expr in sequence:
        Bindings = Engine.createBindings()
        Engine.setBindings(Bindings, ScriptContext.ENGINE_SCOPE)
        print '\n+----Expr "%s" Ref %s ' % (expr, ref)
        run_setundefined(expr, ref)


main()


Reply via email to