Ivan Porto Carrero
2008-Mar-18 01:05 UTC
[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
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
http://rubyforge.org/pipermail/ironruby-core/attachments/20080318/502dac1e/attachment.html
Ivan Porto carrero
2008-Mar-18 02:25 UTC
[Ironruby-core] hosting ironruby: globals confusion
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 Carrero 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-- Posted via http://www.ruby-forum.com/.
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<int>(?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<int>>(?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: ironruby-core-bounces at rubyforge.org [mailto:ironruby-core-bounces at
rubyforge.org] On Behalf Of Ivan Porto Carrero
Sent: Monday, March 17, 2008 6:05 PM
To: ironruby-core at rubyforge.org
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
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
http://rubyforge.org/pipermail/ironruby-core/attachments/20080319/940cd7cd/attachment-0001.html