Python C API vs Ruby C API

Hi Everyone

I am trying to decided whether to embed Ruby or Python.

It looks like Ruby is not ideal for embedding but it also sounds like it
is doable as long as it’s called from main, is that true?

The Ruby C API looks lighter but much easier to work with.

Is VALUE the only type?

Is it true that I do not have to manually increment and decrement values
as well?

I was also wondering about extending Ruby. If I create a C module FOO
and another module POO, can FOO call functions from POO or is there a
way to make them visible? I might like to call TK from another C module

Any feedback or corrections on this topic would be appreciated.

Thanks-Patrick

Matz was at the Texas Ruby Conference this year and he mentioned there
is a
version of Ruby he has been working on that designed for embedded stuff.
I
didn’t get all the details, maybe somebody else knows more about it.
But, don’t
toss out Ruby yet, sounds like it might be the solution.

Wayne

On Wed, Feb 20, 2013 at 9:00 AM, Wayne B. [email protected]
wrote:

Matz was at the Texas Ruby Conference this year and he mentioned there is a
version of Ruby he has been working on that designed for embedded stuff. I
didn’t get all the details, maybe somebody else knows more about it. But,
don’t
toss out Ruby yet, sounds like it might be the solution.

Wayne

That’s mruby

Subject: Python C API vs Ruby C API
Date: mer 20 feb 13 11:57:22 +0900

Quoting Patrick ([email protected]):

The Ruby C API looks lighter but much easier to work with.

Once you get the hang, it is very straightforward. I do not know
Python, but compared with JNI, Ruby’s way of interacting with C code
is a pleasure to work with.

Is VALUE the only type?

Ruby being a pure OO language, everything is an object, and thus only
one type needs to travel through the border. But once you have a
VALUE, you can potentially access the whole object (i.e. call all of
its methods) from the C world. For those classes that are most often
used (numbers, strings, arrays and hashes, to name a few), there are
helping functions. You need to learn them, but once you learned them,
things work well. If you look at Ruby’s source code, you will find
tons of examples. Under /ext you will find all those libraries that
are shipped with Ruby and which have C code.

Is it true that I do not have to manually increment and decrement
values as well?

If you mean reference counts, the only cases when some complexity
appears is when you pass VALUEs to C and you want to use them after
the method call has returned (in background threads, for
example). Otherwise, the objects you create from C are correctly
garbage-collected. When you create you own Ruby classes in C, you
assign to them a C structure, which is allocated for each instance at
object creation, and which you can access from C-code methods. There
you can safely store all C stuff that you will need along the life of
the object. You must provide a function where your stuff is freed,
which is called when the object is GCed.

I was also wondering about extending Ruby. If I create a C module
FOO and another module POO, can FOO call functions from POO or is
there a way to make them visible? I might like to call TK from
another C module

The classes and modules you create from C become full-fledged Ruby
classes and modules. You can add C methods to classes you define under
Ruby, and vice-versa.

I suggest that you download the Ruby source. Inside the directory you
will find a file called

README.EXT

which has much information about this topic. I personally needed a
good chunk of time and effort to make sense of that, but it has not
been wasted time.

Carlo

Hi Patrick,

On 21/02/13 01:27, Patrick wrote:

I am trying to decided whether to embed Ruby or Python.

It looks like Ruby is not ideal for embedding but it also sounds like
it
is doable as long as it’s called from main, is that true?

The Ruby C API looks lighter but much easier to work with.

I’ve done both.

This isn’t going to be a popular opinion given the list (please be
gentle everyone!), but in my experience the Python embedding API was far
easier to work with, clearer, cleaner, and better documented compared to
Ruby. I don’t like this situation, but it has been my experience thus
far.

Note that I’m assuming MRI, which I’m using. I can’t speak for the other
Ruby variants.

However: Another consideration is choosing an embedded language is what
you ultimately want people to use when writing embedded scripts. Having
used both, and both APIs, I settled on Ruby for my project, because I’d
rather be able to write the embedded code in Ruby than Python. The Ruby
embedding API may be weaker (IMHO), but the Ruby language itself is far
superior (also IMHO). In my case, the additional effort was worth it.

Incidentally, I’ve added my own C++ API over the top in my own code, and
it’s now a breeze to work with. The biggest thing for me was wrapping
over the details of registration/unregistration, as well as calls and
exception management.

I can also confirm that what you want to do is definitely doable. I’m
doing it. :slight_smile:

Is VALUE the only type?

Essentially, yes. Even as handles for opaque data types. Even used as as
a placeholder for anonymous pointers on occasion, which can really mess
with your head sometimes.

Is it true that I do not have to manually increment and decrement
values
as well?

You have to watch out for cases where the garbage collector might come
calling for any VALUES. Essentially, I believe you’re safe as long as
the value is sitting somewhere in the stack, but if you want to be
certain, you need to register the VALUE, and unregister when done, or
otherwise make your data participate in the mark and sweep process. If
you forget this, you will eventually start getting unexplained
segmentation faults.

Note that when you’ve got everything working fine, it’s extremely
stable.

I was also wondering about extending Ruby. If I create a C module FOO
and another module POO, can FOO call functions from POO or is there a
way to make them visible? I might like to call TK from another C
module

I believe so, but I’ve not done it. I have made calls in C++ to a Ruby
script which has called a registered function back in my C++ code- it’s
an essential part of my code, so I can confirm that this variant is 100%
possible. :slight_smile:

Any feedback or corrections on this topic would be appreciated.

I hope this helps.

I’d also check out those other posts re mruby. I don’t know anything
about it, but I’ll probably be checking it out myself. :slight_smile:

Garth