2015-12-16 47 views
3

我目前正在努力学习Nim(它正在慢慢地发展 - 不能投入太多时间)。另一方面,为了获得一些工作代码,我想用Ruby创建一个Nim应用程序的部分原型。在nim应用程序中包含mruby是否可能/容易?

由于mruby允许在C应用程序中嵌入ruby子集,并且由于nim允许将任意C代码编译为函数,所以感觉这应该是相对直接的。有人做过这个吗?

我特别寻找使用Nim的时髦宏特性打破内联ruby代码的方法。我要去尝试我自己,但我想有人会尝试它和/或想出更优雅的解决方案比我在我目前的学习:)的状态

回答

3

https://github.com/micklat/NimBorg

这是一个项目的目标有点类似。它目前的目标是python和lua,但使用相同的技术来与Ruby进行交互应该不会太难。

有位于稔几个特点,在流畅的方式与外国语言接口帮助:使用

1)拨打国际长途稔红宝石尼姆dot operators

这是一个有点像红宝石method_missing。 您可以在Nim中定义类似RubyValue的类型,该类型将具有点运算符,可将foo.barfoo.bar(baz)之类的表达式转换为适当的Ruby方法调用。这些参数可以传递给像toRubyValue这样的泛型函数,它们可以被各种Nim和C类型重载,以便自动将它们转换为右侧的Ruby类型。

2)从红宝石

在大多数脚本语言调用稔,有注册一个外国的类型,常常在具有要填充每导出的类型一旦特定数据结构所描述的方法。您可以使用一些通用编程和Nim的变量来自动创建并缓存通过点运算符传递给Ruby的每种类型所需的数据结构。将会有一个像getRubyTypeDesc(T: typedesc)这样的通用proc,它可能依赖于typeinfo,typetraits或用户提供的某些重载的特效,定义必须为该类型导出的内容。

现在,如果你真的想依靠mruby(因为你有它的经验),你可以看看使用.emit. pragma直接输出mruby代码块。然后,您可以要求Nim编译器generate only source code,您将在第二步中编译,或者您可以更改编译该项目时Nim将调用的编译器可执行文件(这在上面链接的相同部分进行了说明)。

+0

哇,一些优秀的指针在那里,谢谢! – user208769

0

这是我到目前为止发现的。

从mruby执行中获取返回值并不像我想象的那么容易。这就是说,大量的试验和错误之后,这是我发现得到一些mruby代码来执行的最简单的方法:

const mrb_cc_flags = "-v -I/mruby_1.2.0_path/include/ -L/mruby_1.2.0_path/build/host/lib/" 
const mrb_linker_flags = "-v" 
const mrb_obj = "/mruby_1.2.0_path/build/host/lib/libmruby.a" 
{. passC: mrb_cc_flags, passL: mrb_linker_flags, link: mrb_obj .} 
{.emit: """ 
    #include <mruby.h> 
    #include <mruby/string.h> 
""".} 

proc ruby_raw(str:cstring):cstring = 
    {.emit: """ 
    mrb_state *mrb = mrb_open(); 
    if (!mrb) { printf("ERROR: couldn't init mruby\n"); exit(0); } 
    mrb_load_string(mrb, `str`); 
    `result` = mrb_str_to_cstr(mrb, mrb_funcall(mrb, mrb_top_self(mrb), "test_func", 0)); 
    mrb_close(mrb); 
    """.} 

proc ruby*(str:string):string = 
    echo ruby_raw("def test_func\n" & str & "\nend") 
    "done" 

let resp = ruby """ 
    puts 'this was a puts from within ruby' 
    "this is the response" 
""" 

echo(resp) 

我敢肯定,你应该能够省略一些编译器标志在配置良好的环境中的文件开始处,例如,通过正确设置LD_LIBRARY_PATH(并非最不重要的,因为这会使代码的可移植性)

一些到目前为止,我所遇到的问题:

  • 我被迫mrb_funcall使用,因为,出于某种原因,铛似乎认为mrb_load_string函数返回一个int,尽管所有的C代码我能找到和文档和几个人在网上说,否则:

    error: initializing 'mrb_value' (aka 'struct mrb_value') with an expression of incompatible type 'int' 
        mrb_value mrb_out = mrb_load_string(mrb, str); 
          ^  ~~~~~~~~~~~~~~~~~~~~~~~~~ 
    
  • 的mruby/string.h中头球需要mrb_str_to_cstr,否则你会遇到段错误。 RSTRING_PTR似乎也可以正常工作(至少在没有string.h的情况下提供了一个明智的错误),但是如果将它作为上面的单线程写入,它将执行两次函数。

我打算继续写一些稍微习惯的nim,但是这已经完成了我现在需要的。

相关问题