SL Unit-II
SL Unit-II
require 'mkmf‘
create_header
create_makefile
'foobar'
ruby extconf.rb
which will create a few files for you (Makefile & extconf.h)
Now create foobar.c, this name comes from the create_makefile line in extconf.rb.
You can change it if you want but it has to match your .c filename for this to work.
foobar.c
#include "ruby.h"
#include "extconf.h"
void Init_foobar()
{
// Your C code goes here
}
This is the basic skeleton of your C extension.
• You can compile this by running make, and what you get is a .so file which
you can load into your Ruby application using require
Writing A Ruby Method From C
• You can create c functions that you can call from
your Ruby code
• All the Ruby methods have to return a VALUE.
A VALUE is a Ruby object.
• Example:
VALUE rb_return_nil() { return Qnil; }
Now we need to attach this function to a Ruby
class or module. You can create a new class or
use an existing one.
• Here I’m creating a module:
void Init_foobar() {
VALUE mod = rb_define_module("RubyGuides");
Rb_define_method(mod, “print_hello”,
rb_print_hello,0);
}
• You can use the rb_define_method method to
attach the C function to this module.
The arguments are:
ARGUMENT DESCRIPTION
Now run make again to compile the extension, and try it like
this:
require 'foobar’
include RubyGuides
print_hello
Ruby objects in C
• When working with Ruby objects in C, you'll interact with Ruby's C
API to manipulate and utilize Ruby objects from within your C code.
• Here's a basic overview of how you can work with Ruby objects in
C:
and crashes.
– Ruby's garbage collector handles memory management for Ruby objects,
but you may need to manually manage memory for any C objects you
create.
Ruby objects in C.
– Many C API functions return special values to indicate errors, so you need
• Other immediate values (true, false, and nil) are represented in C as the
constants Qtrue, Qfalse, and Qnil, respectively
Working with strings
• Ruby String objects are actually references to an
RString structure, and the RString structure contains
both a length and a pointer field.
• we can access the structure via the RSTRING macro.
– VALUE str;
– RSTRING(str)->len → length of the Ruby string
– RSTRING(str)->ptr → pointer to string storage
String Value
• The String Value method checks to see if its operand
is a String. If not, it tries to invoke to_str on the
object, throwing a Type Error exception if it can’t.
Working with other objects
• When VALUEs are not immediate, they are pointers to one of
the defined Ruby object structures
• The structures for the basic built-in classes are defined in ruby.h
and are named RClassname: RArray, RBignum, RClass, RData,
RFile, RFloat, RHash, RObject, RRegexp, RString, and RStruct.
• To check a particular VALUE use the macro TYPE(obj) will return
a constant representing the C type of the given object:
T_OBJECT, T_STRING, and so on
Example
VALUE obj;
switch (TYPE(obj))
{
case T_NIL:
/* handle NilClass */
break;
case T_FIXNUM:
/* handle Fixnum */
break;
case T_STRING:
/* handle String */
break;
/* ... */
}
Array Example:
RARRAY
VALUE arr;
RARRAY(arr)->len
RARRAY(arr)->capacity
RARRAY(arr)->ptr
Writing Ruby In C
Ruby program
class Test
def initialize
@arr = Array.new
end
def add(anObject)
@arr.push(anObject)
end
end
The equivalent code in C should look somewhat familiar.
#include "ruby.h"
static VALUE t_init(VALUE self)
{
VALUE arr;
arr = rb_ary_new();
rb_iv_set(self, "@arr", arr);
return self;
}
static VALUE t_add(VALUE self, VALUE anObject)
{
VALUE arr;
arr = rb_iv_get(self, "@arr");
rb_ary_push(arr, anObject);
return arr;
VALUE cTest;
void Init_Test()
{
cTest = rb_define_class("Test", rb_cObject);
rb_define_method(cTest, "initialize", t_init, 0);
rb_define_method(cTest, "add", t_add, 1);
}
Juke Box Extension
Juke Box Extension Example
// jukebox.c
#include <ruby.h>
#include <stdio.h>
module Jukebox
extend self
def self. play(song _ name)
Jukebox . play _ song(song _name)
end
end
# Example 1: Integer
print_type(42) # Output: The type of 42 is Integer
# Example 2: String
print_type("Hello, world!") # Output: The type of "Hello, world!" is String
# Example 3: Array
print_type([1, 2, 3]) # Output: The type of [1, 2, 3] is Array
# Example 4: Hash
print_type({name: "Alice", age: 30}) # Output: The type of {:name=>"Alice", :age=>30} is Hash
person = Person.new
person.name = "Bob"
person.age = 25
print_type(person)