What scope you would like the instance of BuildMetaData to appear in?
There are basically 2 possibilities:
1) global
Any global Ruby constants will appear in Runtime.Globals dictionary. So you can
just assign the instance into a constant:
MyInstance = Horn::Core::Dsl::BuildMetaData.new
and get it back in C# via Globals.GetVariable("MyInstance")
2) in a DLR execution scope
This is a little bit more tricky since Ruby doesn't have a concept of execution
scopes (unlike Python that has modules). IronRuby has a hook in method
definition that publishes a method defined on a "main" object into the DLR
scope. The "main" object is a singleton of Object class that Ruby creates for
top-level scope self:
> ruby -e 'p self'
main
In IronRuby you can do this:
foo.rb:
def self.my_method
123
end
C#:
var scope = engine.ExecuteFile("foo.rb");
var my_method = scope.GetVariable<Func<int>>("my_method")
Console.WriteLine(my_method());
I'm still looking for improvements to DLR scope interop, so this might actually
change in future.
Tomas
-----Original Message-----
From: [email protected]
[mailto:[email protected]] On Behalf Of Paul Cowan
Sent: Monday, March 16, 2009 4:40 PM
To: [email protected]
Subject: Re: [Ironruby-core] Accessing the return value from a Dsl
Hi,
For anyone who is interested, I managed to solve this by creating a
singleton to house an instance of the BuildMetaData class.
My Ruby code ended up looking like this:
module MetaBuilder
module Dsl
module Main
def install(name, &block)
yield self if block_given?
end
def get_from(name, url)
puts name
puts url
end
def description(desc)
meta.metadata.Description = desc
end
class MetaDataAccessor
attr_accessor :metadata
private
def initialize
@metadata = Horn::Core::Dsl::BuildMetaData.new
end
public
def self.instance
@@instance ||= new
end
def self.get_metadata
@metadata
end
end
end
end
end
def meta
MetaBuilder::Dsl::Main::MetaDataAccessor.instance
end
class ClrAccessor
def get_build_metadata
meta.metadata
end
end
include MetaBuilder::Dsl::Main
I created the MetaDataAccessor to keep a singleton BuildMetaData
instance.
I could not work out the C# code to access a fully qualified class that
is nested in between modules so I created the ClrAccessor class to
provide access from the Clr.
My C# code ended up looking like this:
var engine = Ruby.CreateEngine();
engine.Runtime.LoadAssembly(typeof(BuildMetaData).Assembly);
engine.ExecuteFile(buildFile);
var klass = engine.Runtime.Globals.GetVariable("ClrAccessor");
var instance = engine.Operations.CreateInstance(klass);
buildMetaData = (BuildMetaData)engine.Operations.InvokeMember(instance,
"get_build_metadata");
I am fairly sure there is an easier way but for me it is progress.
Any input into this "round the houses" approach would be appreciated.
Cheers
Paul
Paul Cowan wrote:
> Hi,
>
> I am trying to create a Dsl which will have instances that live in
> individual Dsl .rb files and then run them from the CLR.
>
> I want to create and set the values of the Clr object in IronRuby and
> then somehow have access to the CLR object after the .rb Dsl instance
> file has run.
>
> Here is my Clr object which is very simple at the moment:
>
> namespace Horn.Core.Dsl
> {
> public class BuildMetaData : IBuildMetaData
> {
> public string Description { get; set; }
> }
> }
>
> I have the following module which I am using to specify my Dsl and which
> will create an instance of the BuildMetaData specified above:
>
> module MetaBuilder
> module Dsl
> module Main
> attr_accessor :metadata
> def install(name, &block)
> @metadata = Horn::Core::Dsl::BuildMetaData.new
> yield self if block_given?
> end
>
> def description(desc)
> @metadata.Description = desc
> end
>
> def get_metadata
> @metadata
> end
>
> end
> end
> end
>
> include MetaBuilder::Dsl::Main
>
> I somehow want to be able to get the @metadata property from the Clr
> code after an instance of the Dsl has ran.
>
> An instance of the Dsl looks like this currently:
>
> install :horn do
> description "A .NET build and dependency manager"
> end
>
> My C# code looks like this currently:
>
> var engine = Ruby.CreateEngine();
> engine.Runtime.LoadAssembly(typeof(BuildMetaData).Assembly);
> engine.ExecuteFile(buildFile);
> var klass = engine.Runtime.Globals.GetVariable("get_metadata");
>
> Is there anyway I can get at the @metadata property without having to
> pollute the Dsl instance?
>
> For that matter is my approach reasonable or is there perhaps a better
> way?
>
> Thanks in advance
>
> Paul
--
Posted via http://www.ruby-forum.com/.
_______________________________________________
Ironruby-core mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/ironruby-core
_______________________________________________
Ironruby-core mailing list
[email protected]
http://rubyforge.org/mailman/listinfo/ironruby-core