Доступ к возвращаемому значению из IronRuby Dsl - PullRequest
1 голос
/ 16 марта 2009

Я пытаюсь создать Dsl, который будет иметь экземпляры, которые живут в отдельные файлы Dsl .rb, а затем запустите их из CLR.

Я хочу создать и установить значения объекта Clr в IronRuby и затем каким-то образом иметь доступ к объекту CLR после экземпляра .rb Dsl файл запущен.

Вот мой объект 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

Я хочу получить свойство @metadata от Clr. код после запуска экземпляра 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 Ответ

2 голосов
/ 17 марта 2009

Для тех, кто заинтересован, мне удалось решить эту проблему, создав синглтон для размещения экземпляра класса 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");

Я вполне уверен, что есть более простой путь, но для меня это прогресс.

Буду признателен за любой вклад в этот подход "вокруг дома".

...