【问题标题】:Accessing the return value from an IronRuby Dsl从 IronRuby Dsl 访问返回值
【发布时间】:2009-03-16 17:32:13
【问题描述】:

我正在尝试创建一个 Dsl,该 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 实例?

【问题讨论】:

    标签: ironruby


    【解决方案1】:

    对于任何感兴趣的人,我设法通过创建一个 单例来容纳 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");
    

    我相当肯定有一个更简单的方法,但对我来说这是进步。

    对这种“四处走动”方法的任何意见将不胜感激。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-08
      • 2014-02-07
      • 1970-01-01
      相关资源
      最近更新 更多