$ bundle gem my_awesome_gem
$ cd my_awesome_gem
$ mkdir -p ext/my_awesome_gem
my_awesome_gem/my_awesome_gem.gemspec
spec.add_development_dependency "rake-compiler"
my_awesome_gem/Rakefile
require "rake/extensiontask"
Rake::ExtensionTask.new("my_awesome_gem") do |ext|
ext.lib_dir = "lib/my_awesome_gem"
end
my_awesome_gem/ext/my_awesome_gem/extconf.rb
require 'mkmf'
create_makefile('my_awesome_gem')
my_awesome_gem/ext/my_awesome_gem/my_awesome_gem.c
#include "ruby.h"
VALUE MyAwesomeGemModule = Qnil;
void Init_my_awesome_gem()
{
MyAwesomeGemModule = rb_define_module("MyAwesomeGem");
rb_init_awesome_class();
}
my_awesome_gem/ext/my_awesome_gem/my_awesome_gem.c
#include "ruby.h"
#include "awesome_class.h"
// ...
void Init_my_awesome_gem()
{
MyAwesomeGemModule = rb_define_module("MyAwesomeGem");
rb_init_awesome_class();
}
my_awesome_gem/ext/my_awesome_gem/awesome_class.h
#include "ruby.h"
void rb_init_awesome_class();
my_awesome_gem/ext/my_awesome_gem/awesome_class.c
#include "awesome_class.h"
VALUE AwesomeClass = Qnil;
extern VALUE MyAwesomeGemModule;
void rb_init_awesome_class()
{
AwesomeClass = rb_define_class_under(MyAwesomeGemModule, "AwesomeClass", rb_cObject);
}
my_awesome_gem/ext/my_awesome_gem/awesome_class.h
#include "ruby.h"
void rb_init_awesome_class();
VALUE rb_awesome_class_say_hi(VALUE self);
VALUE rb_awesome_class_say_hi_to(VALUE self, VALUE r_name);
my_awesome_gem/ext/my_awesome_gem/awesome_class.c
#include "awesome_class.h"
VALUE AwesomeClass = Qnil;
extern VALUE MyAwesomeGemModule;
void rb_init_awesome_class()
{
AwesomeClass = rb_define_class_under(MyAwesomeGemModule, "AwesomeClass", rb_cObject);
rb_define_method(AwesomeClass, "say_hi", rb_awesome_class_say_hi, 0);
rb_define_method(AwesomeClass, "say_hi_to", rb_awesome_class_say_hi, 1);
}
VALUE rb_awesome_class_say_hi(VALUE self)
{
return rb_str_new2("Hello!");
}
VALUE rb_awesome_class_say_hi_to(VALUE self, VALUE r_name)
{
VALUE r_greeting = rb_str_new2("Hello, ");
rb_str_append(r_greeting, r_name);
rb_str_append(r_greeting, INT2NUM(33));
return r_greeting;
}
my_awesome_gem/lib/my_awesome_gem.rb
require 'my_awesome_gem/my_awesome_gem'
$ rake clean compile
Defines the module named module_name
.
VALUE AwesomeNewModule = rb_define_module("Awesome");
Defines a function called method_name
under the module ruby_module
. Expects argc
arguments and calls implementation
when invoked in Ruby.
VALUE rb_module_say_hi(VALUE klass)
{
VALUE r_hello = rb_str_new2("Hello!");
return r_hello;
}
void Init_example()
{
VALUE AwesomeNewModule = rb_define_module("Awesome");
rb_define_module_function(AwesomeNewModule, "say_hi", rb_module_say_hi, 0);
}
Defines a constant under the Ruby Module or Class ruby_module_or_class
with the name constant_name
and value value
.
void Init_example()
{
VALUE AwesomeNewModule = rb_define_module("Awesome");
rb_define_const(AwesomeNewModule, "UNIVERSAL_ANSWER", INT2NUM(42));
}
Defines a class under the Ruby module ruby_module
called class_name
and inheriting from super_class
.
void Init_example()
{
VALUE AwesomeNewModule = rb_define_module("Awesome");
rb_define_module_function(AwesomeNewModule, "say_hi", rb_module_say_hi, 0);
VALUE AwesomeClass = rb_define_class_under(AwesomeNewModule, "AwesomeClass", rb_cObject);
}
Defines a class method called method_name
under the class ruby_class
. Expects argc
arguments and calls implementation
when invoked in Ruby.
VALUE rb_class_say_hi(VALUE klass)
{
VALUE r_hello = rb_str_new2("Hello!");
return r_hello;
}
void Init_example()
{
VALUE AwesomeNewModule = rb_define_module("Awesome");
VALUE AwesomeClass = rb_define_class_under(AwesomeNewModule, "AwesomeClass", rb_cObject);
rb_define_singleton_method(AwesomeClass, "say_hi", rb_class_say_hi, 0);
}
Defines an instance called method_name
under the class ruby_class
. Expects argc
arguments and calls implementation
when invoked in Ruby.
VALUE rb_class_say_hi(VALUE klass)
{
VALUE r_hello = rb_str_new2("Hello!");
return r_hello;
}
void Init_example()
{
VALUE AwesomeNewModule = rb_define_module("Awesome");
VALUE AwesomeClass = rb_define_class_under(AwesomeNewModule, "AwesomeClass", rb_cObject);
rb_define_method(AwesomeClass, "say_hi", rb_class_say_hi, 0);
}
Sets the instance variable ivar_name
into the object ruby_object
rb_ivar_set(self, rb_str_new2("@universal_answer"), INT2NUM(42));
Gets the instance variable ivar_name
from the object ruby_object
VALUE r_universal_answer = rb_ivar_get(self, rb_str_new2("@universal_answer"));
// => 42
Creates a new Ruby string with the value c_string
and length length
.
char *message = "Hello, World!";
VALUE r_message = rb_str_new(message, 13);
Creates a new Ruby string with the value string
. Length is inferred from the string, as long as it is null terminated.
char *message = "Hello, World!";
VALUE r_message = rb_str_new2(message);
// => Hello, World!
Creates a copy from a Ruby String object.
char *message = "Hello, World!";
VALUE r_message = rb_str_new2(message);
VALUE r_message_copy = rb_str_dup(r_message);
// => Hello, World!
Concatenates two Ruby String objects, returning a new Ruby String as a result.
VALUE r_hello = rb_str_new2("Hello");
VALUE r_world = rb_str_new2(", World!");
VALUE r_hello_world = rb_str_plus(r_hello, r_world);
// => Hello, World!
Repeats a Ruby String ruby_fixnum_object
times.
VALUE r_times = INT2NUM(16);
VALUE r_string = rb_str_new2("Na");
VALUE r_result = rb_str_times(r_string, r_times);
VALUE r_batman = rb_str_plus(r_result, rb_str_new2(" Batman"));
// => NaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNa Batman!
Grabs a substring of a Ruby String object, starting at begin
with length
characters.
VALUE r_hello_world = rb_str_new2("Hello, World!");
VALUE r_hello = rb_str_substr(r_hello_world, 0, 5);
// => Hello
Takes the c_string
's first length
characters and appends it to an existing Ruby String.
VALUE r_batman = rb_str_times(rb_str_new2("Na"), INT2NUM(16));
rb_str_cat(r_batman, " Batman!", 8);
// => NaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNa Batman!
Takes the c_string
and appends it to an existing Ruby String. Length is inferred from the string, as long as it is null terminated.
VALUE r_batman = rb_str_times(rb_str_new2("Na"), INT2NUM(16));
rb_str_cat2(r_batman, " Batman!");
// => NaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNa Batman!
Appends ruby_string_object_2
into ruby_string_object_1
.
VALUE r_batman = rb_str_times(rb_str_new2("Na"), INT2NUM(16));
rb_str_append(r_batman, rb_str_new2(" Batman!"));
// => NaNaNaNaNaNaNaNaNaNaNaNaNaNaNaNa Batman!
Concatenates ruby_object
into ruby_string_object
. If ruby_object
is a Fixnum between 0 and 255, then it is converted to a character before it is copied. Otherwise, this function behaves exactly the same as rb_str_append
.
VALUE r_dull_hello_world = rb_str_new2("Hello, World");
rb_str_concat(r_dull_hello_world, INT2NUM(33));
// => Hello, World!
Takes a Ruby String object and converts it to a NULL terminated char *
VALUE r_hello_world = rb_str_new2("Hello, World!");
char *hello_world = StringValueCStr(r_hello_world);
// => Hello, World!
Creates a new Ruby Array object with 0 elements.
VALUE r_boring_empty_ary = rb_ary_new();
// => []
Creates a new Ruby Array object with size
elements.
VALUE r_array = rb_ary_new2(10);
Stores value
(a Ruby object) on the index index
in the array ruby_array
.
VALUE r_array = rb_ary_new2(1);
rb_ary_store(r_array, 0, rb_str_new2("Hello!"));
// => ["Hello!"]
Stores value
(a Ruby object) at the end of the array ruby_array
.
VALUE r_array = rb_ary_new2(1);
rb_ary_push(r_array, rb_str_new2("Hello!"));
// => ["Hello!"]
Stores value
(a Ruby object) at the beginning of the array ruby_array
.
VALUE r_array = rb_ary_new2(2);
rb_ary_push(r_array, rb_str_new2("World!"));
rb_ary_unshift(r_array, rb_str_new2("Hello"));
// => ["Hello", "World!"]
Removes the last element off of the array ruby_array
and returns it.
VALUE r_array = rb_ary_new2(2);
rb_ary_push(r_array, rb_str_new2("Hello"));
rb_ary_push(r_array, rb_str_new2("World!"));
VALUE r_world = rb_ary_pop(r_array);
// => World!
Removes the first element off of the array ruby_array
and returns it.
VALUE r_array = rb_ary_new2(2);
rb_ary_push(r_array, rb_str_new2("Hello"));
rb_ary_push(r_array, rb_str_new2("World!"));
VALUE r_hello = rb_ary_shift(r_array);
// => Hello
Returns the array entry at index index
VALUE r_array = rb_ary_new2(2);
rb_ary_push(r_array, rb_str_new2("Hello"));
rb_ary_push(r_array, rb_str_new2("World!"));
VALUE r_hello = rb_ary_entry(r_array, 0);
// => Hello
Creates and returns a copy of the array ruby_array
.
VALUE r_array = rb_ary_new2(2);
rb_ary_push(r_array, rb_str_new2("Hello"));
rb_ary_push(r_array, rb_str_new2("World!"));
VALUE r_array_copy = rb_ary_dup(r_array);
// => ["Hello", "World!"]
Invokes the to_s
on the array.
VALUE r_array = rb_ary_new2(2);
rb_ary_push(r_array, rb_str_new2("Hello"));
rb_ary_push(r_array, rb_str_new2("World!"));
VALUE r_array_str = rb_ary_to_s(r_array);
# => "[\"Hello\", \"World!\"]"
Creates a Ruby String by converting the elements of the array ruby_array
to Strings and joining them by ruby_string_object
. If Qnil
is passed, then no separator is used.
VALUE r_array = rb_ary_new2(2);
rb_ary_push(r_array, rb_str_new2("Hello"));
rb_ary_push(r_array, rb_str_new2("World!"));
VALUE r_greeting = rb_ary_join(r_array, rb_str_new2(", "));
# => "Hello, World!"
Reverts the order of the array ruby_array
.
VALUE r_array = rb_ary_new2(2);
rb_ary_push(r_array, rb_str_new2("Hello"));
rb_ary_push(r_array, rb_str_new2("World!"));
VALUE r_array_copy = rb_ary_reverse(r_array);
// => ["World!", "Hello"]
Same as calling Array()
in Ruby.
VALUE r_value = INT2NUM(42);
VALUE r_array = rb_ary_to_ary(r_value);
// => [42]
Creates a new Ruby Hash
VALUE r_hash = rb_hash_new();
// => {}
Sets the key
as value
in the hash ruby_hash
. All of the 3 parameters have to be Ruby objects.
VALUE r_hash = rb_hash_new();
rb_hash_aset(r_hash, rb_str_new2("universal_answer"), INT2NUM(42));
// => {"universal_answer" => 42}
Gets the value under key
in the hash ruby_hash
. Both parameters have to be Ruby objects.
VALUE r_hash = rb_hash_new();
rb_hash_aset(r_hash, rb_str_new2("universal_answer"), INT2NUM(42));
VALUE r_universal_answer = rb_hash_aref(r_hash, rb_str_new2("universal_answer"));
// => 42
Returns the proc that was given to the method.
if(rb_block_given_p()) {
VALUE r_proc = rb_block_proc();
}
Returns 1 if a block was given to the method. Otherwise, returns 0.
if(rb_block_given_p()) {
VALUE r_proc = rb_block_proc();
}
Yields ruby_object
.
if(rb_block_given_p()) {
VALUE r_val = INT2NUM(42);
r_yield(r_val);
}
Yields the values.
if(rb_block_given_p()) {
r_yield_values(INT2NUM(42), DBL2NUM(3.1415));
}