Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support accessing variables of the interactive Sources via Context#getBindings() #2030

Closed
eregon opened this issue Jun 9, 2020 · 4 comments
Assignees
Labels
Milestone

Comments

@eregon
Copy link
Member

eregon commented Jun 9, 2020

Relates to #2024 and #1838

We'd like to support this:

context.eval(Source.newBuilder("ruby", "foo = 14", "test").interactive(true).buildLiteral());
context.eval(Source.newBuilder("ruby", "foo", "test").interactive(true).buildLiteral()); // 14, already works

context.getBindings("ruby").getMember("foo"); // 14, not yet supported
context.getBindings("ruby").putMember("foo", 42); // not yet supported
context.eval(Source.newBuilder("ruby", "foo", "test").interactive(true).buildLiteral()); // 42, // not yet supported

So that context.getBindings(anyLanguage).get/putMember("foo") generally works.

That's probably reasonable to support for interactive Sources.
We should look at how to handle the automatic printing of values with interactive Sources as that's probably unwanted in most cases, e.g., for snippets in a polyglot notebook.

If we want to do it for non-interactive Sources then it becomes a lot more complicated.
An idea might be that the language bindings would be a scope of local variables above top-level local variables in a file (e.g., my_local = 42 in a.rb).
A bit like my_ruby_binding.eval(File.read("a.rb")) would work.
The complication is how should we parse and execute something like p foo in a e.g. file Source from a.rb? Is foo a local variable (set from the language binding), or is it a method call?
We could maybe decide dynamically, but would that be intuitive semantics? Probably not.
Maybe it's OK to decide based on the current set of language binding variables at parse time?
But then parsing is not independent of the language bindings, which seems dangerous given Sources can be cached and so Source.create("ruby", "foo") might reuse an existing CallTarget which thought foo was a method call.

cc @fniephaus @chumer

@eregon eregon added the polyglot label Jun 9, 2020
@eregon eregon self-assigned this Jun 9, 2020
@eregon
Copy link
Member Author

eregon commented Jun 9, 2020

Once we implement this we'll probably want to no longer expose Ruby's global variables such as $my_global_variable in the language bindings, as local variables should be used instead, and global variables are considered kind of deprecated.

@eregon
Copy link
Member Author

eregon commented Aug 14, 2020

For now we'll implement this for interactive Sources, as there it's well defined. Tracked internally as GR-15673.

@eregon
Copy link
Member Author

eregon commented Aug 14, 2020

That means local variables of the interactive Binding and Object methods might overlap: #1838
Probably unavoidable, and seems best to give priority to local variables of the interactive Binding.

@eregon
Copy link
Member Author

eregon commented Jan 15, 2021

This is now implemented as of 31d0558.
So things like bindings.putMember("forty_two", 42); work, and those top-level local variables can be accessed from interactive Sources:
31d0558#diff-f6c3b1548713de849c4aca4a5f9fa32e3f84fced6b484cfffe0941adcf3529cc


I wonder if maybe we should treat all Sources like interactive Sources, and pass them through Binding#eval.
I think that would be confusing if the Source comes from a file, but other than it might be fine.
Going through Binding#eval might also make it harder to cache Context#eval calls.

@eregon eregon closed this as completed Jan 15, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant