2014-12-05 2 views
2
내가 멀티 스레드 스크립트를로드하고 Nashorn의 평가 및 종류의 충격적인 행동을 얻을 실험있어

:멀티 스레드 Nashorn : o.constructor는 === o.constructor 준다 거짓

// having some object o loaded in another thread 
print(o.constructor === o.constructor); // false 
print(o.constructor === Object); // false as well 
print(o.foo === o.foo); // true - OK 

을 어떻게이 단일 스크립트 엔진 내에서 가능합니까? 위의 o은 객체 리터럴 표기법을 사용하여 만든 객체입니다 (다른 스레드에서). o.constructor을 인쇄하면 보통 function Object() { [native code] };이됩니다.

print({}.constructor === {}.constructor); // true 

모든 아이디어 : 동시에

?

업데이트

그것은이 전혀 스레딩을 멀티 관련이없는 있었다 밝혀졌다. 자세한 내용은 내 대답을 참조하십시오.

+1

각 스레드는 아마도 Object 생성자의 자체 복사본을 가지고 있습니까? 브라우저의 다른 창과 같은 종류입니까? 그것은'window.frames [0] .Object! == window.Object'입니다. –

+0

@JuanMendes 그게 정확히 그게 겠지요. 예외 ... 음, "외계인"개체에 대한 참조 인 경우, 나는 그것이 어떻게 작동하는지 잘 모르겠습니다. OP가 설정 한 것에 대해 더 많이 알면 도움이 될 것입니다. 마치 ScriptEngine 하나 또는 여러 개입니까? – Pointy

+0

o.constructor가 자신과 동일하지 않은 이유를 설명합니까? – Tvaroh

답변

1

이것은 멀티 스레딩과 관련이 없습니다. 내가 잘못 bindings 매개 변수를 사용했다

object Test extends App { 
    val engine = new ScriptEngineManager().getEngineByName("nashorn") 
    var o = engine.eval("({ foo: 'bar' })") 
    var result = engine.eval("(o.constructor === o.constructor)", new SimpleBindings() { 
    put("o", o) 
    }) 
    print(result) // false 
} 

: 여기에 문제를 재현하는 간단한 스칼라 프로그램입니다. 대신, 기존의 bindings을 가져 와서 '내부 수정'해야합니다. 나는 이것이 여전히 o.constructor === o.constructor이 false가되어야한다고 확신하지는 않지만 적어도 지금은 작동한다. 수정 된 버전 :

object Test extends App { 
    val engine = new ScriptEngineManager().getEngineByName("nashorn") 
    var o = engine.eval("({ foo: 'bar' })") 

    val bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE) 
    bindings.put("o", o) 

    var result = engine.eval("(o.constructor === o.constructor)", bindings) 
    print(result) // true 
} 
+1

이것이 예상되는 동작이든 아니건간에 분명 직관적이거나 명확하게 문서화되지 않았습니다. Nashorn에 관해서 새로운 바인딩에서 객체를 평가하는 것이 엔진 바인딩을 사용하는 것과 다르게 동작하는 이유를 설명하는 내용은 없습니다. 그래도 잘 잡는다. –