How do you use the C language to produce a ruby gem?
Asked Answered
L

1

15

I would like to see some source code or maybe a link to some that gives at least a stub for writing ruby gems in the C languages (C++?? is that possible too?)

Also, some of you may know that Facebook compiles some of their code natively as php extensions for better performance. Is anyone doing this in Rails? If so, what has been your experience with it? Have you found it to be useful?

Thanks.

Edit: I guess I'll answer my own question with some stuff I learned today but I'm going to leave the question open for another answer because I'd like to see what others have to say on this topic

Lyall answered 16/5, 2010 at 13:40 Comment(1)
I would suggest finding an open source project such as RMagick or Nokogiri and crib from that.Nonstop
L
20

Ok, so I sat down a buddy of mine that is good with C. I have been showing him Ruby and he digs it. When we met last night I told him that you could write Ruby gems in C, which intrigued him. Here is what we found:

Tutorials/Examples

http://www.eqqon.com/index.php/Ruby_C_Extension

http://drnicwilliams.com/2008/04/01/writing-c-extensions-in-rubygems/

http://www.rubyinside.com/how-to-create-a-ruby-extension-in-c-in-under-5-minutes-100.html

ruby-doc (ruby.h source code)

http://ruby-doc.org/doxygen/1.8.4/ruby_8h-source.html

Here is some source code that we wrote to test it out as well:

Open up a terminal:

prompt>mkdir MyTest
prompt>cd MyTest
prompt>gedit extconf.rb

Then you put this code in extconf.rb

# Loads mkmf which is used to make makefiles for Ruby extensions
require 'mkmf'

# Give it a name
extension_name = 'mytest'

# The destination
dir_config(extension_name)

# Do the work
create_makefile(extension_name)

Save the file then write MyTest.c

#include "ruby.h"

// Defining a space for information and references about the module to be stored internally
VALUE MyTest = Qnil;

// Prototype for the initialization method - Ruby calls this, not you
void Init_mytest();

// Prototype for our method 'test1' - methods are prefixed by 'method_' here
VALUE method_test1(VALUE self);
VALUE method_add(VALUE, VALUE, VALUE);

// The initialization method for this module
void Init_mytest() {
MyTest = rb_define_module("MyTest");
rb_define_method(MyTest, "test1", method_test1, 0);
rb_define_method(MyTest, "add", method_add, 2);
}

// Our 'test1' method.. it simply returns a value of '10' for now.
VALUE method_test1(VALUE self) {
int x = 10;
return INT2NUM(x);
}

// This is the method we added to test out passing parameters
VALUE method_add(VALUE self, VALUE first, VALUE second) {
int a = NUM2INT(first);
int b = NUM2INT(second);
return INT2NUM(a + b);
}

From the prompt you then need to create a Makefile by running extconf.rb:

prompt>ruby extconf.rb
prompt>make
prompt>make install

You can then test it out:

prompt>irb
irb>require 'mytest'
irb>include MyTest
irb>add 3, 4 # => 7

We did a benchmark test and had ruby add 3 and 4 together 10 million times and then make a call to our C extension 10 million times as well. The result was that using only ruby it took 12 seconds to complete this task while using the C extension only took 6 seconds! Also note, that most of this processing is handing the job off to C to complete the task. In one of those tutorials the writer used recursion (Fibonacci sequence) and reported that the C extension took 51 times faster!

Lyall answered 18/5, 2010 at 16:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.