Упрощение DSL, написанного для приложения C # с помощью IronPython

Благодаря предложениям из предыдущего вопроса, Я пытаюсь использовать IronPython, IronRuby и Boo для создания DSL для моего приложения C #. Шаг первый - IronPython из-за большего количества пользователей и базы знаний. Если я могу заставить что-то здесь хорошо работать, я могу просто остановиться.

Вот моя проблема:

Я хочу, чтобы мой скрипт IronPython имел доступ к функциям класса Lib. Прямо сейчас я могу добавить сборку в среду выполнения IronPython и импортировать класс, выполнив оператор в созданной мной области:

// load 'ScriptLib' assembly
Assembly libraryAssembly = Assembly.LoadFile(libraryPath);
_runtime.LoadAssembly(libraryAssembly);

// import 'Lib' class from 'ScriptLib'
ScriptSource imports = _engine.CreateScriptSourceFromString("from ScriptLib import Lib", SourceCodeKind.Statements);
imports.Execute(_scope);

// run .py script:
ScriptSource script = _engine.CreateScriptSourceFromFile(scriptPath);
script.Execute(_scope);

Если я хочу запустить Lib :: PrintHello, который является просто оператором в стиле hello world, мой скрипт Python содержит:

Lib.PrintHello()

или (если не статично):

library = new Lib()
library.PrintHello()

Как я могу изменить свою среду так, чтобы я мог просто иметь базовые состояния в скрипте Python следующим образом:

PrintHello
TurnOnPower
VerifyFrequency
TurnOffPower
etc...

Я хочу, чтобы эти сценарии было легко написать непрограммисту. Я не хочу, чтобы они знали, что такое класс и как он работает. IronPython действительно существует, поэтому некоторые базовые операции, такие как for, do, if и определение базовой функции, не требуют написания компилятора для моего DSL.


person cgyDeveloper    schedule 28.08.2009    source источник
comment
Еще уродливее это выглядит в IronRuby, где мне приходится писать ScriptLib :: Lib.PrintHello () Кто-нибудь знаком с IronRuby или IronPython таким образом? Нужен ли мне сценарий установки python для сопоставления всех методов / переменных перед запуском тестового сценария? Я надеялся сделать это на C #.   -  person cgyDeveloper    schedule 29.08.2009


Ответы (1)


Вы должны уметь делать что-то вроде:

var objOps = _engine.Operations;
var lib = new Lib();

foreach (string memberName in objOps.GetMemberNames(lib)) {
    _scope.SetVariable(memberName, objOps.GetMember(lib, memberName));
}

Это получит все члены из объекта lib, а затем вставит их в ScriptScope. Это делается с помощью класса Python ObjectOperations, так что члены, которые вы выберете, будут членами Python. Итак, если вы затем сделаете что-то подобное с IronRuby, тот же код в основном должен работать.

person Dino Viehland    schedule 29.08.2009
comment
Спасибо! Хотел бы я отдать несколько голосов за, я не мог найти способ где-нибудь добавить функции в область видимости. - person cgyDeveloper; 31.08.2009
comment
Похоже, это может не работать в IronRuby. Я не думаю, что он поддерживает свободных участников. Лучшее, что я могу сейчас получить, - это lib.PrintHello. - person cgyDeveloper; 31.08.2009
comment
@cygDeveloper не волнуйтесь, я добавил дополнительный голос за ответ, это определенно правильный путь, мы также создали DSL для наших приложений таким образом - person TimothyP; 02.02.2011