2009-08-28 6 views
9

Dzięki sugestiom z previous question, jestem zajęty wypróbowywanie IronPython, IronRuby i Boo, aby utworzyć DSL dla mojej aplikacji C#. Pierwszym krokiem jest IronPython, ze względu na większą bazę użytkowników i wiedzy. Jeśli uda mi się coś dobrze tu wykorzystać, mogę po prostu przestać.Simplfying DSL napisane dla aplikacji C# z IronPythonem

Oto mój problem:

Chcę, aby mój skrypt IronPython mieć dostęp do funkcji w klasie o nazwie Lib. Teraz mogę dodać zespół do wykonywania IronPython i zaimportować klasę wykonując oświadczenie w zakresie I Utworzono:

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

jeśli chcę uruchomić Lib :: PrintHello, który jest po prostu stwierdzenie hello world styl mój skrypt Pythona zawiera:

Lib.PrintHello() 

lub (jeśli to nie jest statyczna):

library = new Lib() 
library.PrintHello() 

Jak mogę zmienić swoje otoczenie tak, że mogę tylko mieć podstawowe statments w skrypcie Pythona jak jes s:

PrintHello 
TurnOnPower 
VerifyFrequency 
TurnOffPower 
etc... 

Chcę, aby te skrypty były proste do napisania przez programistę. Nie chcę, żeby musieli wiedzieć, czym jest lekcja i jak to działa. IronPython jest właśnie tam, więc niektóre podstawowe operacje, takie jak, czy, jeśli i podstawowa definicja funkcji nie wymagają mojego pisania kompilatora dla mojego DSL.

+0

Wygląda nawet brzydsze w IronRuby gdzie muszę napisać ScriptLib :: Lib.PrintHello() Czy ktoś zna obu IronRuby i IronPython w ten sposób? Czy potrzebuję skryptu konfiguracyjnego Pythona do mapowania wszystkich metod/zmiennych przed uruchomieniem skryptu testowego? Miałem nadzieję, że zrobię to w C#. – cgyDeveloper

Odpowiedz

19

Powinieneś być w stanie zrobić coś takiego:

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

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

ten dostanie wszyscy członkowie z lib objec a następnie wstrzyknąć do ScriptScope. Odbywa się to w klasie Python ObjectOperations, tak aby członkowie, z których korzystasz, będą członkami Pythona. Jeśli więc zrobisz coś podobnego w/IronRuby, ten sam kod powinien w zasadzie zadziałać.

+1

Dzięki! Chciałbym móc oddać wiele głosów w górę, nie mogłem znaleźć sposobu na umieszczenie funkcji w zakresie gdziekolwiek. – cgyDeveloper

+0

Wygląda na to, że to nie działa w IronRuby. Myślę, że nie obsługuje on niezwiązanych członków. Najlepsze, co mogę teraz uzyskać, to lib.PrintHello. – cgyDeveloper

+1

@cygDeveloper nie martw się Dodałem dodatkową wiadomość do odpowiedzi, to zdecydowanie do zrobienia, stworzyliśmy również DSL dla naszych aplikacji w ten sposób – TimothyP