Опростяване на 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