# Hosting ironruby: globals confusion

**URL:** <https://www.ruby-forum.com/t/hosting-ironruby-globals-confusion/132226>\
**Category:** IronRuby\
**Created:** [March 18, 2008, 2:09am UTC](https://www.ruby-forum.com/t/hosting-ironruby-globals-confusion/132226 "2008-03-18T02:09:54Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![xjivan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/x/6f9a4e/32.png) [@xjivan](https://www.ruby-forum.com/u/xjivan)\
**Post date:** [March 18, 2008, 2:09am UTC](https://www.ruby-forum.com/t/hosting-ironruby-globals-confusion/132226/1 "2008-03-18T02:09:54Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![xjivan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/x/6f9a4e/32.png) [@xjivan](https://www.ruby-forum.com/u/xjivan)\
**Post date:** [March 18, 2008, 3:25am UTC](https://www.ruby-forum.com/t/hosting-ironruby-globals-confusion/132226/2 "2008-03-18T03:25:33Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![xjivan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/x/6f9a4e/32.png) [@xjivan](https://www.ruby-forum.com/u/xjivan)\
**Post date:** [March 19, 2008, 11:23pm UTC](https://www.ruby-forum.com/t/hosting-ironruby-globals-confusion/132226/3 "2008-03-19T23:23:46Z")

</div>

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: removed\_email\_address@domain.invalid  
[[mailto:removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)] On Behalf Of Ivan Porto  
Carrero  
Sent: Monday, March 17, 2008 6:05 PM  
To: removed\_email\_address@domain.invalid  
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
