2011-02-24 29 views
0

我试图重新使用一些我在ASP.NET MVC 2项目中编写的ruby类。我遇到的问题是如果一个类在模块内,我似乎无法实例化它。如果我将模块移动到模块外面,它可以正常工作。这里是我想实例化的类的缩小版本:实例化C中的模块中的ruby类#

module Generator 
    class CmdLine 
    attr_accessor :options 

    def initialize(output) 
    end 

    def run(args=[]) 
    end 
    end 
end 

如果注释掉模块部分,我可以创建对象。难道我做错了什么?下面是C#代码:

var engine = Ruby.CreateEngine(); 
var searchPaths = engine.GetSearchPaths().ToList(); 
searchPaths.Add(@"c:\code\generator\lib"); 
searchPaths.Add(@"C:\Ruby-ri-192\lib\ruby\1.9.1"); 
engine.SetSearchPaths(searchPaths); 

engine.ExecuteFile(@"c:\code\generator\lib\generator\generator_cmd_line.rb"); 
var rubyCmdLineObj = engine.Runtime.Globals.GetVariableNames(); 
// These lines works when I comment out the module 
// var genCmdLineObj = engine.Runtime.Globals.GetVariable("CmdLine"); 
// var cmdLineObj = engine.Operations.CreateInstance(genCmdLineObj); 
// var results = engine.Operations.InvokeMember(cmdLineObj, "run"); 
// return Content(results); 
var sb = new StringBuilder(); 
foreach (var name in rubyCmdLineObj) 
{ 
    sb.AppendFormat("{0} ", name); 
} 

return Content(sb.ToString()); 

我身边有一个工作 - 创建一个单独的类,我可以从C#中调用,但如果我没有这样做,我宁愿不做。任何指导将不胜感激。

回答

0

我知道这是怎样的一个黑客/解决办法,但我设法做到这一点是这样的:

接下来的代码添加到您的ruby文件的末尾:

def hack(s) 
    eval(s) 
end 

现在你的C#代码看起来像这样:

var engine = Ruby.CreateEngine(); 

var scope = engine.ExecuteFile(@"c:\code\generator\lib\generator\generator_cmd_line.rb"); 

var genCmdLineObj = engine.Execute(String.Format("hack('{0}::{1}')", "Generator", "CmdLine"), scope); 
var cmdLineObj = engine.Operations.CreateInstance(genCmdLineObj); 
var results = engine.Operations.InvokeMember(cmdLineObj, "run"); 
return Content(results); 

一种黑客,但嘿,它的作品! :)

+0

谢谢谢伊!这有点黑客,但它的作品。感谢您花时间回答! – Rob 2011-02-27 16:54:25

0

我会创建一个新的IronRuby项目,将原始的Ruby代码和端口/编译到.NET库中。

不需要再打电话了。你有一些可以从C#本地调用的东西。

+0

我想重新使用我已经有了。如果我必须重写/端口,我会找到另一种方法来获得我所需要的。我可能是错的,但我不相信你可以将IronRuby项目编译成DLL。我错了吗? – Rob 2011-02-24 16:05:55

+0

@Rob - 不,你不能直接将IronRuby编译成DLL本身。但是,您可以将其托管在C#DLL中并将调用包装到DLR中。根据Ruby代码,你不应该有太多的改变,如果有的话。 – 2011-02-24 16:16:04

+0

酷我会检查出来。谢谢Justin。 – Rob 2011-02-24 16:17:20

0

@Shay Friedman提出的解决方案是不必要的。

gen.rb

CSHARP

void Main() 
{ 
    var engine = Ruby.CreateEngine(); 
    var buffer = new MemoryStream(); 
    engine.Runtime.IO.SetOutput(buffer, new StreamWriter(buffer)); 
    engine.ExecuteFile(@"c:\temp\gen.rb"); 
    ObjectHandle handle = engine.ExecuteAndWrap("Generator::CmdLine.new('the output')"); 
    var scope = engine.CreateScope(); 
    scope.SetVariable("myvar", handle); 
    engine.Execute("myvar.run", scope); 
    engine.Operations.InvokeMember(handle.Unwrap(), "run", "InvokeMember"); 
    buffer.Position = 0; 
    Console.WriteLine(new StreamReader(buffer).ReadToEnd()); 
} 

输出

Hello from cmdLine with the output [] 
Hello from cmdLine with the output InvokeMember