【问题标题】:How to use ErrorListener for IronRuby如何为 IronRuby 使用 ErrorListener
【发布时间】:2012-02-17 07:34:29
【问题描述】:

我有一个 C# 程序来执行 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);
    }
}

Ruby 文件:

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

【问题讨论】:

  • 你解决过这个问题吗?

标签: c# ironruby


【解决方案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!");
}

【讨论】:

  • 这似乎对我不起作用,使用 IronRuby 1.13(NuGet 上的最新版本)。 MyErrorListener.ErrorReported 函数永远不会触发。
【解决方案2】:

我研究了这个问题终于找到了解决方法,就是先在Manger下面写你的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 关键字的字符(如(~、`、^ 等)或您创建了任何语法错误,则它会在运行时编译,否则错误将在 ScriptSource 的编译方法上捕获,并且ErrorListener 类的对象将被填充,我们将找到 ErrorCode 等。如果您使用了 Ruby 库中未定义的方法,例如您输入了这样的数字转换方法

    @abc.to_

如果不正确,则会在 MissingMethodException 块中被捕获

正确的方法是

    @abc.to_f

如果你得到 Error Other 然后这些(例如除以零异常)然后将被捕获在异常块中

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多