Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 834141
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 15, 20262026-05-15T04:37:51+00:00 2026-05-15T04:37:51+00:00

I’ve written (in JavaScript) an interactive read-eval-print-loop that is encapsulated within an object. However,

  • 0

I’ve written (in JavaScript) an interactive read-eval-print-loop that is encapsulated
within an object. However, I recently noticed that toplevel function definitions specified to the interpreter do not appear to be ‘remembered’ by the interpreter. After some diagnostic work, I’ve reduced the core problem to this:

   var evaler = {
     eval: function (str)
     {
       return eval(str);
     },
   };

   eval("function t1() { return 1; }");         // GOOD
   evaler.eval("function t2() { return 2; }");  // FAIL

At this point, I am hoping that the following two statements wil work as expected:

print(t1());     // => Results in 1 (This works)
print(t2());     // => Results in 2 (this fails with an error that t2 is undefined.)

What I get instead is the expected value for the t1 line, and the t2 line fails with an error that t2 is unbound.

IOW: After running this script, I have a definition for t1, and no defintion for t2. The act of calling eval from within evaler is sufficiently different from the toplevel call that the global definition does not get recorded. What does happen is that the call to
evaler.eval returns a function object, so I’m presuming that t2 is being defined and stored in some other set of bindings that I don’t have access to. (It’s not defined as a member in evaler.)

Is there any easy fix for this? I’ve tried all sorts of fixes, and haven’t stumbled upon one that works. (Most of what I’ve done has centered around putting the call to eval in an anonymous function, and altering the way that’s called, chainging __parent__, etc.)

Any thoughts on how to fix this?

Here’s the result of a bit more investigation:


tl;dr: Rhino adds an intermediate scope to the scope chain when calling a method on an instance. t2 is being defined in this intermediate scope, which is immediately discarded. @Matt: Your ‘hacky’ approach might well be the best way to solve this.

I’m still doing some work on the root cause, but thanks to some quality time with jdb, I now have more understanding of what’s happening. As has been discussed, a function statement like function t1() { return 42; } does two things.

  • It creates an anonymous instance of a function object, like you’d get with the expression function() { return 42; }
  • It binds that anonymous function to the current top scope with the name t1.

My initial question is about why I’m not seeing the second of these things happen when I call eval from within a method of an object.

The code that actually performs the binding in Rhino appears to be in the function org.mozilla.javascript.ScriptRuntime.initFunction.

    if (type == FunctionNode.FUNCTION_STATEMENT) {
         ....
                scope.put(name, scope, function);

For the t1 case above, scope is what I’ve set to be my top-level scope. This is where I want my toplevel functions defined, so this is an expected result:

main[1] print function.getFunctionName()
 function.getFunctionName() = "t1"
main[1] print scope
 scope = "com.me.testprogram.Main@24148662"

However, in the t2 case, scope is something else entirely:

main[1] print function.getFunctionName()
 function.getFunctionName() = "t2"
main[1] print scope
 scope = "org.mozilla.javascript.NativeCall@23abcc03"

And it’s the parent scope of this NativeCall that is my expected toplevel scope:

main[1] print scope.getParentScope()
 scope.getParentScope() = "com.me.testprogram.Main@24148662"

This is more or less what I was afraid of when I wrote this above: ” In the direct eval case, t2 is being bound in the global environment. In the evaler case, it’s being bound ‘elsewhere'” In this case, ‘elsewhere’ turns out to be the instance of NativeCall… the t2 function gets created, bound to a t2 variable in the NativeCall, and the NativeCall goes away when the call to evaler.eval returns.

And this is where things get a bit fuzzy… I haven’t done as much analysis as I’d like, but my current working theory is that the NativeCall scope is needed to ensure that this points to evaler when execution in the call to evaler.eval. (Backing up the stack frame a bit, the NativeCall gets added to the scope chain by Interpreter.initFrame when the function ‘needs activation’ and has a non-zero function type. I’m assuming that these things are true for simple function invocations only, but haven’t traced upstream enough to know for sure. Maybe tomorrow.)

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-15T04:37:51+00:00Added an answer on May 15, 2026 at 4:37 am

    Your code actually is not failing at all. The eval is returning a function which you never invoke.

    print(evaler.eval("function t2() { return 2; }")()); // prints 2
    

    To spell it out a bit more:

    x = evaler.eval("function t2() { return 2; }"); // this returns a function
    y = x(); // this invokes it, and saves the return value
    print(y); // this prints the result
    

    EDIT

    In response to:

    Is there another way to create an interactive read-eval-print-loop than to use eval?

    Since you’re using Rhino.. I guess you could call Rhino with a java Process object to read a file with js?

    Let’s say I have this file:

    test.js

    function tf2() {
      return 2;
    }
    
    print(tf2());
    

    Then I could run this code, which calls Rhino to evaluate that file:

    process = java.lang.Runtime.getRuntime().exec('java -jar js.jar test.js');
    result = java.io.BufferedReader(java.io.InputStreamReader(process.getInputStream()));
    print(result.readLine()); // prints 2, believe it or not
    

    So you could take this a step further by WRITING some code to eval to a file, THEN calling the above code …

    Yes, it’s ridiculous.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Ask A Question

Stats

  • Questions 421k
  • Answers 422k
  • Best Answers 0
  • User 1
  • Popular
  • Answers
  • Editorial Team

    How to approach applying for a job at a company ...

    • 7 Answers
  • Editorial Team

    What is a programmer’s life like?

    • 5 Answers
  • Editorial Team

    How to handle personal stress caused by utterly incompetent and ...

    • 5 Answers
  • Editorial Team
    Editorial Team added an answer use more universal unique identifier data type like UNIQUEIDENTIFIER (UUID)… May 15, 2026 at 11:08 am
  • Editorial Team
    Editorial Team added an answer Yes you can. If you have MyClass m; m.doSomething(); The… May 15, 2026 at 11:08 am
  • Editorial Team
    Editorial Team added an answer Figure out where the AJAX method submits to. It might… May 15, 2026 at 11:08 am

Trending Tags

analytics british company computer developers django employee employer english facebook french google interview javascript language life php programmer programs salary

Top Members

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.