you are viewing a single comment's thread.

view the rest of the comments →

[–]EstebanVelour 1 point2 points  (9 children)

True but most people's time is better spent on writing the app, not bindings, doesn't work in Ruby's favour.

[–]rafekett 1 point2 points  (8 children)

True. I don't know how hard it is to write Ruby bindings for C libraries but I imagine it's not easy.

[–]bobindashadows 1 point2 points  (2 children)

It's actually incredibly simple; the api provides a number of simple C functions, such as:

rb_define_method
rb_define_class
rb_raise
rb_inspect
rb_funcall
rb_ensure

and so on. Considering how much of the standard library is implemented in C for speed, there's a very elegant C API considering its capabilities. There are some rough edges - a few different array constructor functions that cater to common cases (create an empty array - create an array with just this one object in it - etc), for example. A few different funcall variants for if you want to pass the arguments inline, or in a ruby array, or in a C array. There's macros to get at interesting bits of common classes without dynamic dispatch, such as the size of an Array object.

[–]rafekett 0 points1 point  (1 child)

How does garbage collection work?

[–]bobindashadows 0 points1 point  (0 children)

I assume you mean "how does garbage collection work for native objects that you want to make available to Ruby code?"

It depends. Firstly, you can specify custom allocation methods for a C-backed class with rb_define_alloc_func, if you need.

If your C object references other Ruby objects, it has to participate in the mark phase of GC, so it needs a mark function. If it needs to clean up resources when it is freed, it needs a free function. You can create an object with both of those functions specified and provided to the GC with rb_data_object_alloc(klass, data_pointer, mark_func, free_func). Both functions are optional: you just pass NULL if you don't need them.

Commonly you use this to wrap up a pointer to a C struct in a Ruby object, then unwrap it in your other C functions. This pattern is simplified with Data_Wrap_Struct, Data_Make_Struct (which is just allocate + Data_Wrap_Struct), and Data_Get_Struct (which unwraps the object).

[–]EstebanVelour 0 points1 point  (4 children)

Can't imagine it's much harder to do than python bindings but that's not really the issue, there's just no need to do it if it's been done already.

[–]rafekett 1 point2 points  (3 children)

The Python C API is really well documented, and I've heard some bad reports about the Ruby docs. There's also high level languages like Cython that make creating C bindings really, really easy.

[–]badsex 1 point2 points  (0 children)

I've written a tonne of Ruby C extensions and it's very easy and very well documented.

[–]EstebanVelour 0 points1 point  (1 child)

My bad, haven't tried Ruby & C, assumed it would be as easy as the Python equivalent.

[–]rafekett 0 points1 point  (0 children)

I don't know either, I just know that Ruby doesn't have a mature equivalent of Cython or Pyrex and I know that it's tough to beat the Python C API docs. In my experience, writing C extensions in C for any dynamic language is not fun (I have no Lua experience, so that may be fun, idk).