How to use ErrorListener for IronRuby

2019-02-26 22:10发布

I have a C# program to execute an IronRuby script. But before doing that, I'd like to compile the file first to see if there is any errors. But it seems the ErrorListener does not work well. Is there anything wrong with my code?

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 file:

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
2条回答
闹够了就滚
2楼-- · 2019-02-26 22:33

What you're trying to do seems to not actually work. Not sure if it's a bug or not, though.

To workaround it, just execute the code inside a try/catch block and look for MissingMethodExecption. Pay attention that this also will not help if the syntax error is inside a method since IronRuby (or any other dynamic language) doesn't do anything with "nested" code until it actually executes it.

So in general, I think you won't get a lot of value from what you're trying to do.

The try/catch code sample:

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!");
}
查看更多
我欲成王,谁敢阻挡
3楼-- · 2019-02-26 22:37

I researched on this problem finally found the solution that is first write your ErrorListener Class in following Manger.

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;
    }
}

then

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

Because Ironruby is DLR therefore it compiles On RunTime if characters which are not the keyword of IronRuby like (~ ,` , ^ and so On) OR you have created any Syntax Error other then Error will capture on Compile Method of ScriptSource and the object of ErrorListener Class will be filled and we will find ErrorCode etc. if you have used a Method which is not defined in Ruby Library for example you have typed the method for Number Conversion like this

    @abc.to_

which is not correct then it will be caught in MissingMethodException Block

Correct method is

    @abc.to_f

and if you got Error Other then these (like Divide by Zero Exception)then that will be caught in Exception Block

查看更多
登录 后发表回答