从IronRuby Dsl访问返回值

时间:2009-03-16 17:32:14

标签: ironruby

我正在尝试创建一个具有实例的Dsl 单个Dsl .rb文件,然后从CLR运行它们。

我想在IronRuby和中创建和设置Clr对象的值 然后以某种方式访问​​.rb Dsl实例后的CLR对象 文件已经运行。

这是我的Clr对象,目前非常简单:

namespace Horn.Core.Dsl
{
    public class BuildMetaData : IBuildMetaData
    {
        public string Description { get; set; }
    }
}

我有以下模块,我用它来指定我的Dsl和哪个 将创建上面指定的BuildMetaData实例:

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

我想以某种方式希望能够从Clr获取@metadata属性 在Dsl的实例运行后的代码。

Dsl的一个实例目前看起来像这样:

install :horn do
  description "A .NET build and dependency manager"
end

我的C#代码目前看起来像这样:

var engine = Ruby.CreateEngine();
engine.Runtime.LoadAssembly(typeof(BuildMetaData).Assembly);
engine.ExecuteFile(buildFile);
var klass = engine.Runtime.Globals.GetVariable("get_metadata");

无论如何,我可以在不必使用@metadata属性 污染Dsl实例?

1 个答案:

答案 0 :(得分:2)

对于任何有兴趣的人,我设法通过创建一个来解决这个问题 单例来容纳BuildMetaData类的实例。

我的Ruby代码最终看起来像这样:

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

我创建了MetaDataAccessor以保留单个BuildMetaData 实例

我无法计算出C#代码来访问一个完全限定的类 嵌套在模块之间,所以我创建了ClrAccessor类 提供来自Clr的访问。

我的C#代码最终看起来像这样:

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");

我相信有一种更简单的方法,但对我来说这是进步。

对此“围绕房屋”方法的任何意见都将不胜感激。