2012-02-17 28 views
2

我有一个C#程序来执行IronRuby脚本。但在此之前,我想先编译文件以查看是否有任何错误。但它似乎ErrorListener不能正常工作。我的代码有什么问题吗?如何为IronRuby使用ErrorListener

class Program 
{ 
    static void Main(string[] args) 
    { 
     try 
     { 
      ScriptEngine engine = null; 
      engine = Ruby.CreateEngine(); 

      ScriptSource sc = engine.CreateScriptSourceFromFile("MainForm.rb"); 
      ErrorListener errLis = new MyErrorListener(); 
      sc.Compile(errLis); 
    } 
} 

class MyErrorListener : ErrorListener 
{ 
    public override void ErrorReported(ScriptSource source, string message, Microsoft.Scripting.SourceSpan span, int errorCode, Microsoft.Scripting.Severity severity) 
    { 
     Console.WriteLine(message); 
    } 
} 

红宝石文件:

require "mscorlib" 
require "System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" 
require "System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" 

include System::Windows::Forms 
dfasdf error here 
class MainForm < Form 
def initialize() 
    self.InitializeComponent() 
end 

def InitializeComponent() 
    # 
    # MainForm 
    # 
    self.Name = "MainForm" 
    self.Text = "HelloRubyWin" 
end 
end 
+0

你有没有解决这个问题? – ashes999 2014-09-02 15:21:05

回答

1

什么你正在试图做的,似乎不实际工作。但不知道它是否是一个错误。

要解决它,只需执行try/catch块内的代码并查找MissingMethodExecption。请注意,如果语法错误位于方法内,这也无济于事,因为IronRuby(或任何其他动态语言)在“嵌套”代码执行任何操作后才会执行任何操作。

所以一般来说,我认为你不会从你想要做的事情中获得很多价值。

的try/catch语句的代码示例:

ScriptEngine engine = null; 
engine = Ruby.CreateEngine(x => { x.ExceptionDetail = true; });   

ScriptSource sc = engine.CreateScriptSourceFromFile("MainForm.rb"); 
ErrorListener errLis = new MyErrorListener(); 
sc.Compile(errLis); 

try 
{ 
    dynamic d = sc.Execute(); 
} 
catch (MissingMethodException e) 
{ 
    Console.WriteLine("Syntax error!"); 
} 
+0

这似乎不适用于我,IronRuby 1.13(最新的NuGet)。 MyErrorListener.ErrorReported函数从不会触发。 – ashes999 2014-09-02 14:59:11

0

我对这个问题的研究终于发现,是先写你的ErrorListener类在下面管理器解决方案。

public class IronRubyErrors : ErrorListener 
{ 
    public string Message { get; set; } 
    public int ErrorCode { get; set; } 
    public Severity sev { get; set; } 
    public SourceSpan Span { get; set; } 
    public override void ErrorReported(ScriptSource source, string message, Microsoft.Scripting.SourceSpan span, int errorCode, Microsoft.Scripting.Severity severity) 
    { 
     Message = message; 
     ErrorCode = errorCode; 
     sev = severity; 
     Span = span; 
    } 
} 

然后

var rubyEngine = Ruby.CreateEngine(); 
ScriptSource src = rubyEngine.CreateScriptSourceFromFile("test.rb"); 
IronRubyErrors error = new IronRubyErrors(); 
src.Compile(error); 
if (error.ErrorCode != 0) 
{ 
    MessageBox.Show(string.Format("Discription {0} \r\nError at Line No.{1} and Column No{2}", error.Message, error.span.Start.Line, error.span.Start.Column)); 
} 

try 
{ 
    if (error.ErrorCode == 0) 
    { 
     var res = src.Execute(); 
    } 
} 
catch (MissingMethodException ex) 
{ 
    MessageBox.Show(ex.Message); 
} 
catch (Exception ex) 
{ 
    MessageBox.Show(ex.Message); 
} 

由于IronRuby的是DLR因此它编译运行时,如果字符,这不是IronRuby的喜欢的关键字(〜,`,^等),或者你所创建的任何语法如果您使用了未在Ruby库中定义的方法,例如您已经键入了数字转换的方法,那么其他错误将会在ScriptSource的Compile Method上捕获并且ErrorListener类的对象将被填充,并且我们将找到ErrorCode等。像这样

@abc.to_ 

未然后纠正它会在MissingMethodException块中捕获

正确的方法是

@abc.to_f 

,如果你有错误其他然后这些(如零异常鸿沟),那么会被抓住在例外区域