Hosting ironruby: globals confusion

Hi,

I updated the hosting wiki page to work with the current revision. But
this
raises a couple of questions.

I’m just working my way through the dlr-hosting-spec.
And if I read it correctly then there are 3 levels of
hosting/integration
possible.

Now AFAICT level 1 hosting is only supposed to work with external files,
because for compiling to a source unit you need a different class than
either ScriptRuntime or ScriptScope
I was expecting when I set a variable in globals that it becomes a
global
variable or do I have to access that differently?

So I tried the following bit of code:

ScriptRuntime runtime = IronRuby.CreateRuntime();
runtime.Globals.SetVariable(“version”, “simplest test possible with a
variable succeeded”);
runtime.ExecuteFile(“commands.rb”);

and the file commands.rb contains one line of ruby code: puts $version
put the output of that code is nil instead of the expected string.

This returns nil. I have trouble reconciling that with what I read in
the
hosting spec. Because this should be totally doable with Level 1 hosting
or
am I wrong in this assumption?

When I create a ScriptRuntime shouldn’t it then have a DefaultScope
(Globals) that is language-specific to ruby because I create it with the
static method on IronRuby?

Also for as far as i understand it a ScriptScope is like a container for
your scripts so globals in that container are only alive in that script
scope?

Anyway when I go and use level 2 hosting because I need the execution
context and script engine and these are only introduced in level 2
hosting.
I can set global variables and then things do work

ScriptRuntime runtime = IronRuby.CreateRuntime();
ScriptEngine rubyengine = IronRuby.GetEngine(runtime);
RubyExecutionContext ctx = IronRuby.GetExecutionContext(runtime);

ctx.GlobalVariables[SymbolTable.StringToId(“variable”)] = “simplest test
possible with a variable succeeded”;
runtime.ExecuteSourceUnit(rubyengine.CreateScriptSourceFromString(“puts
“#{$variable}””));

And in the level 2 hosting sample the RubyExecutionContext seems to do
what
I was expecting ScriptScope to do.

Am I reading the spec wrong ?

Cheers
Ivan

I figured out that ScriptRuntime and ScriptScope are still language
agnostic.
So if you want to host IronRuby in your application you’re always
looking at Level 2 hosting as soon as you want some communication
between Host and IronRuby, because you need the RubyEngine.

I’m still a bit unsure of how the ScriptScope ties in to everything.

I understand that the ScriptRuntime is like the complete host for dyn
languages and you can create a bunch of them they will always run in
isolation.
But how does ScriptScope work because so far I’ve been unsuccessful in
talking to a ScriptScope ?

Is this hosting API still too much of a moving target to really get into
it?

Ivan Porto C. wrote:

Hi,

I updated the hosting wiki page to work with the current revision. But
this
raises a couple of questions.

I’m just working my way through the dlr-hosting-spec.
And if I read it correctly then there are 3 levels of
hosting/integration
possible.

Now AFAICT level 1 hosting is only supposed to work with external files,
because for compiling to a source unit you need a different class than
either ScriptRuntime or ScriptScope
I was expecting when I set a variable in globals that it becomes a
global
variable or do I have to access that differently?

So I tried the following bit of code:

ScriptRuntime runtime = IronRuby.CreateRuntime();
runtime.Globals.SetVariable(“version”, “simplest test possible with a
variable succeeded”);
runtime.ExecuteFile(“commands.rb”);

and the file commands.rb contains one line of ruby code: puts $version
put the output of that code is nil instead of the expected string.

This returns nil. I have trouble reconciling that with what I read in
the
hosting spec. Because this should be totally doable with Level 1 hosting
or
am I wrong in this assumption?

When I create a ScriptRuntime shouldn’t it then have a DefaultScope
(Globals) that is language-specific to ruby because I create it with the
static method on IronRuby?

Also for as far as i understand it a ScriptScope is like a container for
your scripts so globals in that container are only alive in that script
scope?

Anyway when I go and use level 2 hosting because I need the execution
context and script engine and these are only introduced in level 2
hosting.
I can set global variables and then things do work

ScriptRuntime runtime = IronRuby.CreateRuntime();
ScriptEngine rubyengine = IronRuby.GetEngine(runtime);
RubyExecutionContext ctx = IronRuby.GetExecutionContext(runtime);

ctx.GlobalVariables[SymbolTable.StringToId(“variable”)] = “simplest test
possible with a variable succeeded”;
runtime.ExecuteSourceUnit(rubyengine.CreateScriptSourceFromString(“puts
“#{$variable}””));

And in the level 2 hosting sample the RubyExecutionContext seems to do
what
I was expecting ScriptScope to do.

Am I reading the spec wrong ?

Cheers
Ivan

Ruby integration into hosting API is not finished yet. Last week I’ve
checked in some basic support for scopes.

“I was expecting when I set a variable in globals that it becomes a
global variable or do I have to access that differently?”

Globals dictionary on ScriptRuntime are actually not the same globals as
Ruby globals. Think of ScriptRuntime.Globals as a top level namespace.
If you load .NET assembly, say mscorlib, into ScriptRuntime, top
namespaces (e.g. “System”) are added to Globals. In IronRuby, you’ll see
content of ScriptRuntime.Globals thru Object class. When searching for a
constant on Object class the ScriptRuntime.Globals is looked up.
Therefore you can do System::Collections in your IronRuby code. See
RubyModule.TryGetConstant.

So the right way of doing what you’re trying to do is (as you have it
below):

var runtime = IronRuby.CreateRuntime();
var ec = IronRuby.GetExecutionContext(runtime);
ec.DefineGlobalVariable(“version”, “foo”);
runtime.ExecuteFile(“commands.rb”);

I’m using the latest bits where I’ve recently added DefineGlobalVariable
method. If you don’t see it yet, use GlobalVariables collection on ec.

As for the ScriptScope. In general, ScriptScope is a host provided
dictionary against which you can execute code. ScriptScope has an
extension for each language that is executed against it. For IronRuby it
is GlobalScopeExtension class. This extension associates the scope with
a singleton self object on top-level scope and with the top-level
binding. The singleton object “type” is defined in MainSingletonOps
class. If file is executed as a regular Ruby source code the singleton
is exactly like in MRI. If executed using hosting API it redefines
method_missing. The method_missing implementation goes to the
ScriptScope’s dictionary. This way the following works:

var scope = engine.CreateScope();
scope.SetVariable(“x”, 1);
scope.SetVariable(“y”, 2);
scope.Execute(“puts x + y”);

In this code, ‘puts’, ‘x’ and ‘y’ are method calls (since there is no
assignment to these identifiers in the code). ‘puts’ get resolved to
Kernel#puts as usual. ‘x’ and ‘y’ don’t exist so ‘method_missing’ is
called as usual in MRI. Since the current ‘self’ object is main
singleton that in IronRuby defines ‘method_missing’, ‘x’ and ‘y’ values
are loaded from the scope.

Note, that this doesn’t work yet:
var scope = engine.CreateScope();
scope.SetVariable(“x”, 1);
scope.SetVariable(“y”, 2);
scope.Execute(“z = x + y”);
var z = scope.GetVariable(“z”);

It’s because ‘z’ is a local variable (it is assigned to in the code) and
therefore it lives on the top-level binding. The plan is to associate
the top-level binding with the scope but we are not there yet.

Instead you can do this:
var scope = engine.CreateScope();
scope.SetVariable(“x”, 1);
scope.SetVariable(“y”, 2);
scope.Execute(“def self.z; x + y; end”);
var z = scope.GetVariable<Function>(“z”)();

This works since methods defined on the singleton are accessible to the
host via the scope.

BTW: John is now working on syncing our TFS with SVN (there is some
issue that needs to be fixed). So some of the changes I’ve done recently
to enable the above scenarios haven’t probably been pushed out yet.

Any feedback on hosting API is welcomed. There are few missing pieces
that are described in the spec but not yet in the code and also IronRuby
is not yet plugged completely into the hosting infrastructure.

Tomas

From: [email protected]
[mailto:[email protected]] On Behalf Of Ivan Porto
Carrero
Sent: Monday, March 17, 2008 6:05 PM
To: [email protected]
Subject: [Ironruby-core] hosting ironruby: globals confusion

Hi,

I updated the hosting wiki page to work with the current revision. But
this raises a couple of questions.

I’m just working my way through the dlr-hosting-spec.
And if I read it correctly then there are 3 levels of
hosting/integration possible.

Now AFAICT level 1 hosting is only supposed to work with external files,
because for compiling to a source unit you need a different class than
either ScriptRuntime or ScriptScope
I was expecting when I set a variable in globals that it becomes a
global variable or do I have to access that differently?

So I tried the following bit of code:

ScriptRuntime runtime = IronRuby.CreateRuntime();
runtime.Globals.SetVariable(“version”, “simplest test possible with a
variable succeeded”);
runtime.ExecuteFile(“commands.rb”);

and the file commands.rb contains one line of ruby code: puts $version
put the output of that code is nil instead of the expected string.

This returns nil. I have trouble reconciling that with what I read in
the hosting spec. Because this should be totally doable with Level 1
hosting or am I wrong in this assumption?

When I create a ScriptRuntime shouldn’t it then have a DefaultScope
(Globals) that is language-specific to ruby because I create it with the
static method on IronRuby?

Also for as far as i understand it a ScriptScope is like a container for
your scripts so globals in that container are only alive in that script
scope?

Anyway when I go and use level 2 hosting because I need the execution
context and script engine and these are only introduced in level 2
hosting. I can set global variables and then things do work

ScriptRuntime runtime = IronRuby.CreateRuntime();
ScriptEngine rubyengine = IronRuby.GetEngine(runtime);
RubyExecutionContext ctx = IronRuby.GetExecutionContext(runtime);

ctx.GlobalVariables[SymbolTable.StringToId(“variable”)] = “simplest test
possible with a variable succeeded”;
runtime.ExecuteSourceUnit(rubyengine.CreateScriptSourceFromString(“puts
“#{$variable}””));

And in the level 2 hosting sample the RubyExecutionContext seems to do
what I was expecting ScriptScope to do.

Am I reading the spec wrong ?

Cheers
Ivan

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs