A tale of C++ native Ruby and RAII

While I was playing with my last project, I wanted to gather the execution time of a few native functions. Doing so in C is a little bit painful: it requires quite a bit of code, temporary variable, and such. One really powerful idiom I liked using while doing C++ was Resource Acquisition Is Initialization (RAII) to do this kind of task. This post will contain two subjects: using RAII to time function execution and using rake-compiler with C++ for native Ruby. So here is a tale of C++ native Ruby and RAII.

What is RAII

In a class, RAII is represented in a really simple way: the constructor acquires something (file handle, lock, etc.) and the destructor releases it.

An example of this is the std::ofstream class. An instance of this class acquires a handle on the given file and the destructor releases it. Therefore, the following is completely valid:

This idiom ensures that the underlying resource gets released correctly in all cases. No need to catch exceptions and rethrow in order to manually close the file, it will be done when the stack unwinds.

Using RAII to time function execution

In order to use RAII to time function execution, I went with a really simple flow:

  • The constructor gets the start time
  • The destructor gets the end time and prints the elapsed time

The code using the previous flow can be found here:

Using this class becomes super simple: create an instance and let it go out of scope. An example of this can be found in this file:

Using rake-compiler with C++

I was expecting some major differences when using C++ instead of C with rake-compiler. Turns out that the tool does most of the heavy lifting. I only needed to put the C++ files in the directory and they got built magically.

There were only a few things that I needed to care about:

  • Ensure that the entrypoints were in an Extern C section in order for the method signatures to be valid
  • Define a typedef to enforce C signatures whenever you call a C Ruby function that requires a function pointer
  • In order to manage memory correctly, remember to delete any allocated instances
Advertisements
Tagged , . Bookmark the permalink.

Leave a Reply