Friday, May 30, 2008

Ruby Predefined Constants/Variables

Constants
ENV # Hash of environment variables
STDIN # IO stream for standard input
STDOUT # IO stream for standard output, most cases the console
STDERR # IO stream for standard error output
RUBY_VERSION # String containing current ruby version
RUBY_RELEASE_DATE # String containing the date in which ruby was compiled
RUBY_PLATFORM # String containing the platform and compiler used to build ruby
ARGV # Array of arguments used to run the ruby file. ARGV[0] is the first argument, not the name of the file.


Variables
$: # Ruby Include Path
$> # STDOUT
$. # Current Line
$! # Latest error message
$@ # location of error
$_ # string last read by gets
$. # line number last read by interpreter
$& # string last matched by regexp
$~ # the last regexp match, as an array of subexpressions
$n # the nth subexpression in the last match (same as $~[n])
$= # case-insensitivity flag
$/ # input record separator
$\ # output record separator
$0 # the name of the ruby script file
$* # the command line arguments
$$ # interpreter's process ID
$? # exit status of last executed child process
$SAFE # safe level (0-4)
$" # Loaded modules, extensions (also $LOADED_FEATURES)

Sunday, May 25, 2008

Mysql Ruby Extension

Installing in Windows

Download mysql dev files from : http://dev.mysql.com/downloads/mysql/5.0.html
Install them in your hard drive. We only need the include and lib files, not the server. Download the zip package.

Download last mysql-ruby extension from http://tmtm.org/downloads/mysql/ruby/ and extract it.

we run extconf.rb with the following parameters:

ruby extconf.rb --with-mysql-include=/path/to/mysql/include --with-mysql-lib=/path/to/libs

By default the mysql installer saves the lib files in the lib/opt.

To compile the extension:

nmake

Now we should have a valid mysql.so file. We need to get the libmysql.dll from the bin folder of the mysql distribution, you can grab it from the zip version.

To test it:

ruby test.rb [hostname [user [passwd [dbname [port [socket [flag]]]]]]]

Saturday, May 24, 2008

Ruby 1.9 C API - Data Conversion

Ruby -> C


char* RSTRING_PTR(VALUE); /* Ruby String to char* */
int RSTRING_LEN(VALUE); /* String length */
char* StringValuePtr(VALUE); /* Returns string representation of any object */
RSTRING StringValue(VALUE); /* Returns Ruby string representation of any object */
int NUM2INT(VALUE); /* Number to Int */
double NUM2DBL(VALUE); /* Double to Int */
VALUE* RARRAY_PTR(RARRAY); /*Returns the pointer to values of a Ruby Array */
int RARRAY_LEN(RARRAY); /* Returns length of Array */


C -> Ruby

/* Integer to Ruby Number*/
INT2NUM(number);
UINT2NUM(number);
DOUBLE2NUM(double); /* Or rb_float_new(double) */
RSTRING rb_str_new(char*, len); /* Returns ruby string from char* and length*/
RSTRING rb_str_new2(char*); /* Returns ruby string from null terminated char* */


Generating Arrays

VALUE array = rb_ary_new(); /* Create the array */
rb_ary_push(array, VALUE); /* Push data into the array */


Generating a Hash

VALUE hash = rb_hash_new();
rb_hash_aset(hash, VALUE key, VALUE);


Get the type of a Ruby VALUE object
rb_type(VALUE);
Possible Types:

#define T_NONE RUBY_T_NONE
#define T_NIL RUBY_T_NIL
#define T_OBJECT RUBY_T_OBJECT
#define T_CLASS RUBY_T_CLASS
#define T_ICLASS RUBY_T_ICLASS
#define T_MODULE RUBY_T_MODULE
#define T_FLOAT RUBY_T_FLOAT
#define T_STRING RUBY_T_STRING
#define T_REGEXP RUBY_T_REGEXP
#define T_ARRAY RUBY_T_ARRAY
#define T_HASH RUBY_T_HASH
#define T_STRUCT RUBY_T_STRUCT
#define T_BIGNUM RUBY_T_BIGNUM
#define T_FILE RUBY_T_FILE
#define T_FIXNUM RUBY_T_FIXNUM
#define T_TRUE RUBY_T_TRUE
#define T_FALSE RUBY_T_FALSE
#define T_DATA RUBY_T_DATA
#define T_MATCH RUBY_T_MATCH
#define T_SYMBOL RUBY_T_SYMBOL
#define T_RATIONAL RUBY_T_RATIONAL
#define T_COMPLEX RUBY_T_COMPLEX
#define T_VALUES RUBY_T_VALUES
#define T_UNDEF RUBY_T_UNDEF
#define T_NODE RUBY_T_NODE
#define T_MASK RUBY_T_MASK


Iterate through a Ruby Hash
We iterate with the function
rb_hash_foreach(hash, iterator_c_function, extra_value);
iterator_c_function is of the form:
int iterator(VALUE key, VALUE value, VALUE extra);
Remeber VALUE is the same size as a void*, this means we can typecast it into whatever we want.
To tell the rb_ruby_foreach() function to continue we return a ST_CONTINUE in the iterator function. We can also return a ST_STOP, ST_DELETE, or ST_CHECK.

Ruby 1.9 C API - Modules

Creating a module:

VALUE module = rb_define_module("name");

Add methods/functions to a module:

rb_define_method_function(module, "name", c_function, argc);

Now the tricky part is that ruby adds a reference to the module when calling the function. c_function would look like this if it were to accept 1 parameter:

VALUE c_function(VALUE module, VALUE arg);

In this case the argc parameter in the rb_define function should be 1 not 2 as you would expect.

Define a constant:

rb_define_const(module_or_class, "NAME", value);

value is a VALUE.

Friday, May 23, 2008

HOW TO specify GCC binary in configure script

Ubuntu installs gcc 4.2 as gcc-4.2 binary. To tell configure to use gcc-4.2 instead of gcc we use the following parameter

./configure CC=gcc-4.2