2013-07-24 33 views
4

我想知道如何將以C擴展名編寫的本機方法添加到預先存在的Ruby類中?我只發現允許你創建新的Ruby類的函數,但沒有一個返回一個預先存在的類。將C本地方法添加到預先存在的Ruby類中

+0

簡單的方法imho將用c-extension定義ruby類,然後用純ruby重新打開它。對?在Ruby中,你不能重新定義一個類,你只需重新打開它並添加到它。 – nathanvda

+0

我沒有遇到任何問題。 AFAIK,相關的C函數 - 例如'rb_define_class'將很高興地「重新打開」類和模塊,因爲它們實際上與MRI Ruby中使用的功能相同。 –

回答

8

是的,你可以。在任何一種情況下,您都使用rb_define_method(或對單例方法使用rb_define_singleton_method)。假設你有交流功能稱爲rb_some_function是預計1個參數(除自參數),你會做

rb_define_method(someClass, 
       "some_function", 
       RUBY_METHOD_FUNC(rb_some_function), 
       1); 

這是給你SomeClass的是否是一個新創建的類(rb_define_class_underrb_define_class創建)或現有課程。您可以使用rb_const_get(與Object的const_get相同)獲取現有類。

someClass = rb_const_get(rb_cObject, rb_intern("SomeClass")); 

rb_define_class也將獲取對您現有的類(類似於紅寶石重新打開類)。如果你嘗試用超類定義一個類並且該類已經存在一個不同的類,它將以類似的方式炸燬。

+0

正如Neil所說,rb_define_class是否重新打開現有類,還是使用rb_const_get更好? – yageek

+3

'rb_const_get(rb_cObject,rb_intern(「Foo」));'類似於將類命名符號'Foo'放入您的代碼中。例如。如果你願意,可以直接在Ruby中寫下「def Foo.bar」(無論出於何種原因)。而'rb_define_class(「Foo」,rb_cObject)'與Ruby'class Foo'中的寫法相同。我會相應地使用它們,這意味着我通常會避免使用'rb_const_get'方法,除非我正在編寫類元編程的擴展 –

+1

如果我期望類存在,我傾向於使用rb_const_get - 如果類不在那裏,那麼我想讓我的代碼炸燬,而不是僅僅創建一個新的類。取決於我感覺到多麼偏執,儘管 –

相關問題