2015-12-16 51 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,但是這已經完成了我現在需要的。

相關問題