2009-08-28 34 views
9

Nhờ các đề xuất từ ​​một previous question, tôi đang bận thử IronPython, IronRuby và Boo để tạo một DSL cho ứng dụng C# của tôi. Bước một là IronPython, do người dùng lớn hơn và cơ sở tri thức. Nếu tôi có thể làm việc gì đó tốt ở đây, tôi có thể dừng lại.Đơn giản hóa DSL được viết cho một ứng dụng C# với IronPython

Đây là vấn đề của tôi:

Tôi muốn tập lệnh IronPython có quyền truy cập vào các chức năng trong lớp có tên Lib. Ngay bây giờ tôi có thể thêm lắp ráp để thời gian chạy IronPython và nhập khẩu các lớp bằng cách thực hiện các tuyên bố trong phạm vi tôi đã tạo:

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

Nếu tôi muốn chạy Lib :: PrintHello, mà chỉ là một tuyên bố chào phong cách thế giới , kịch bản Python của tôi chứa:

Lib.PrintHello() 

hoặc (nếu nó không tĩnh):

library = new Lib() 
library.PrintHello() 

Làm thế nào tôi có thể thay đổi môi trường của tôi để tôi có thể chỉ cần có statments cơ bản trong kịch bản Python như thi s:

PrintHello 
TurnOnPower 
VerifyFrequency 
TurnOffPower 
etc... 

Tôi muốn các script này trở nên đơn giản đối với người không lập trình để viết. Tôi không muốn họ phải biết lớp học là gì hoặc nó hoạt động như thế nào. IronPython là thực sự chỉ có để một số hoạt động cơ bản như cho, làm, nếu, và một định nghĩa chức năng cơ bản không yêu cầu tôi viết một trình biên dịch cho DSL của tôi.

+0

Nó trông có vẻ xấu xí trong IronRuby nơi tôi phải viết ScriptLib :: Lib.PrintHello() Có ai quen thuộc với một trong hai IronRuby hoặc IronPython theo cách này? Tôi có cần một tập lệnh cài đặt python để ánh xạ tất cả các phương thức/biến trước khi chạy một kịch bản thử nghiệm không? Tôi đã hy vọng sẽ làm điều này trong C#. – cgyDeveloper

Trả lời

19

Bạn sẽ có thể làm điều gì đó như:

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

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

này sẽ nhận được tất cả các thành viên từ các objec lib và sau đó tiêm chúng vào ScriptScope. Điều này được thực hiện với lớp Python ObjectOperations để các thành viên bạn nhận được sẽ là các thành viên Python. Vì vậy, nếu bạn sau đó làm một cái gì đó tương tự w/IronRuby cùng một mã cơ bản nên làm việc.

+1

Cảm ơn! Tôi ước tôi có thể đưa ra nhiều phiếu bầu, tôi không thể tìm được cách để đưa các chức năng vào phạm vi ở bất cứ đâu. – cgyDeveloper

+0

Dường như điều này có thể không hoạt động trong IronRuby. Tôi không nghĩ rằng nó hỗ trợ các thành viên không bị ràng buộc. Điều tốt nhất tôi có thể làm bây giờ là lib.PrintHello. – cgyDeveloper

+1

@cygDeveloper đừng lo lắng tôi đã thêm một câu trả lời bổ sung cho câu trả lời, nó chắc chắn là cách để đi, chúng tôi cũng tạo một DSL cho các ứng dụng của chúng tôi theo cách này – TimothyP

Các vấn đề liên quan