0% found this document useful (0 votes)
9 views103 pages

Updated Unit 2 Objects

Uploaded by

karkaruchitha28
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
9 views103 pages

Updated Unit 2 Objects

Uploaded by

karkaruchitha28
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 103

CS513PE DATA ANALYTICS

UNIT II
RUBY
OBJECTS
Dr.D.Magdalene Delighta
Angeline
III CSE
Associate Professor-CSE
JBREC
Introduction

• Ruby is a very pure object-oriented language.


• All values are objects.
• In Ruby, all objects inherit from a class named
Object and share the methods defined by that
class.
What is class?

• A class is a definition of user defined data type.


• It may or may not contain data.
• Inside a class, you can have variables (data
members) called instance variables and member
functions or methods to work on those data
members.
Class Syntax
• A class can be defined using the class keyword.
• The class name should always start with an upper case
letter.
• A class is terminated using the keyword end.

Syntax:
class <ClassName>
…..
end
Example:
class DemoClass
…….
end
What is object?
• An object is an instance of a class which has
its own copy of instance variables.
• Instance variables begin with at the rate (@)
sign.
• There is another type of variables called class
variables.
• These are equivalent to static variables in the
OOP domain.
• Class variables are shared by all objects. These
begin with double at the rate signs (@@).
Example
• Take vehicles as an example, they include car,
truck, van, bus and a sedan; these attributes form
the members of the Vehicle class.
• One vehicle can be distinguished from another
based on these attributes. car is an object of a
vehicle class.
• Vehicles can also contain specific functions, such as
drive, stop, and turn. These functions form the
members of the Vehicle class. Therefore, you can
define a class, including attributes and functions.
Example

• Class : Vehicle
• Object: Car, truck, van, bus and a sedan
• Attributes of a car: Color, Model
• Functions: drive, stop, and turn
Creating Ruby Objects

• In Ruby, new is used to create an object.

Syntax:
objectName = ClassName. new
Example:
obj1 = MyClass. new( parameters )

obj1 is the name of the object


Initialize Methods

• The initialize method is the constructor of the


class.
• This method gets invoked every time an object
is created.
• This method is defined inside the class like any
other method using def keyword.
• The name of this method should be initialize ,
no other names are permitted and it may or
may not accept parameters.
Initialize Method Syntax
Syntax:
class <ClassName>
def initialize()
#Statements to be executed when an object is created.
End
end
Example:
class DemoClass
def initialize()
puts “Object created!”
end
end
Initialize Method Syntax
• The initialize method can be used to initialize instance
variables.
Syntax:
class <ClassName>
def initialize(<param 1>, <param 2>, … <param n>)
@<instance var 2> = <param 1>
@<instance var 2> = <param 2>
…@
<instance var n> = <param n>
#Statements to be executed when an object is created.
End
end
Initialize Method
Example:
class DemoClass
def initialize(x, y, z)
@a = x
@b = y
@c = z
end
end
In the above example, the initialize method accepts
three arguments – x, y and z . When an object is
created and these parameters are passed, the
initialize method will be invoked and inside it, x, y
and z will be assigned to instance variable @a, @b
and @c respectively.
Example
class MyClass # define a class
@@students=0
def initialize(id, name, address) # initialize method
@myID=id
@myName=name
@myAddr=address
end
def information() # declare a method
puts "Student id #@myID"
puts "Student name #@myName"
puts "Student address #@myAddr"
end
def numbers() # declare a method
@@students += 1
puts "Total number of Students: #@@students"
end
end
Example
# create two objects
obj1=MyClass.new("01", "Andy", "Boston")
obj2=MyClass.new("02", "Lisa", "Huston")
# call two methods
obj1.information()
obj1.numbers()
obj2.information()
obj2.numbers()
Output
Student id 01
Student name Andy
Student address Boston
Total number of Students: 1
Student id 02
Student name Lisa
Student address Huston
Total number of Students: 2
Variables in a Ruby Class

Ruby
Variable

Local Instance Class Global


Variable Variable Variable Variable

Start with
lowercase
Start with
letters, Start with $
Start with @ @@. Class
underscore
variables are
shared
across the
inheritance
chain.
Local Variables
• Local variables are the variables that are
defined in a method.
• Local variables are not available outside the
method.
• Local variables start with lowercase letters or
underscores.
• The scope of a local variable limits the range
from class, module, def, or do to the
corresponding end or from left curly braces to
right curly braces.
Local Variables-Example
myVariable = 100 # local variable
puts myVariable

Output
100
Instance Variables
• Instance variables are available across
methods for any particular instance or object.
• That means that instance variables change
from object to object.
• The instance variable starts with an @.
• The value of an uninitialized instance variable
is nil, and a warning is generated after the -w
option is used.
Instance Variables-
Example
# Define a class
class MyClass
def initialize(id, name, address)
@myID=id # instance variable
@myName=name # instance variable
@myAddr=address # instance variable
end
def information()
puts "Student id #@myID"
puts "Student name #@myName"
puts "Student address #@myAddr"
end
end
Class Variables
• Class variables are available across different
objects.
• A class variable belongs to the class and is a
characteristic of a class.
• Class variables start with @@ and must be
initialized before they can be used in the
method definition.
• It is a mistake to refer to an uninitialized class
variable.
• A class variable can be shared in a subclass or
submodule that defines its class or module.
Class Variables-Example
class MyClass
@@students=0 # class variable
def numbers()
@@students += 10 # class variable
puts "Total number of Students: #@@students"
end
end
# create two objects
obj1=MyClass.new
obj2=MyClass.new
# call two methods
obj1.numbers()
obj2.numbers()
Output
Total number of Students: 10
Total number of Students: 20
Global Variables
• Class variables are not available across classes.
• To have a single variable, which is available
across classes, define a global variable.
• Global variables start with $.
• The value of an uninitialized global variable is
nil, and a warning is generated
after the -w option is used.
• Usually global variables are not
recommended.
Global Variables-Example
$global_variable = 200 # this is a global
class ClassA
def showGlobal
puts "The global variable in ClassA: #$global_variable"
end
end
class ClassB
def showGlobal
puts "The global variable in ClassB: #$global_variable"
end
end
classAobj = ClassA.new
classAobj.showGlobal
classBobj = ClassB.new
classBobj.showGlobal
Output
The global variable in ClassA: 200
The global variable in ClassB: 200
Creating Ruby Objects

• In Ruby, new is used to create an object.

Syntax:
objectName = ClassName. new
Example:
obj1 = MyClass. new
obj1 is the name of the object
Creating Ruby Objects with parameters

• When the initialize method is defined to accept


parameters, the exact number of parameters
should be passed using the new keyword.

Syntax:
<object variable> = <Class name>.new(<param 1>,
<param 2>,… <param n>)
Example:
obj = MyClass.new (1, 2, 3)
Example
• class MyClass
def initialize ()
puts "\nObject created!"
end
end
x = MyClass . new
y = MyClass . new
z = MyClass. New
Working with Ruby Objects

• Ruby are objects and all objects are manipulated by


reference.
• When a value is assigned to a variable, reference to
an object is stored into the variable.
Example:
s = "Ruby" # Create a String object. Store a reference to it in s
t=s # Copy the reference to t.

t[-1] = "" # Modify the object through the reference in t.


print s # Access the modified object through s. Prints "Rub".
t = "Java" # t now refers to a different object.
print s,t # Prints "RubJava".
RubRubJavaRuby Ruby Rub RubJava

Example
s = "Ruby"
Output:
print s,"\n“
t=s
Rub
print s,"\n“ RubJava
t[-1] = "" Ruby
print s,"\n“ Ruby
t = "Java"
print s,t
Working with Immediate Objects

• Fixnums and a few other special types (symbols,


true/false/nil, floats?) are assigned as immediate
values.
• Instead of storing a pointer (or reference) to the
value object, the variable stores the value
directly.
• So in a=4 ‘a’ does not hold a reference, but rather
the immediate value 4.
Tests to check for other immediate
values
• FIXNUM_P(value) -> nonzero if value is a
Fixnum
• SYMBOL_P(value) -> nonzero if value is a
Symbol
• NIL_P(value) -> nonzero if value is nil
• RTEST(value) -> nonzero if value is neither nil
nor false
FIXNUM_P(value)
• This macro checks if the given
value is a Fixnum (a fixed-size VALUE my_value =
INT2FIX(42); //
integer). Convert integer to
• In Ruby, Fixnums are a specific Fixnum value
if
type of object used to represent (FIXNUM_P(my_value)
){
integers within a certain range // my_value is a
Fixnum
without needing to allocate } else {
memory for every integer. // my_value is not a
Fixnum
• The macro returns a non-zero }

value if value is indeed a


Fixnum, and zero otherwise.
SYMBOL_P(value)
• This macro checks if the given
VALUE my_value =
value is a Symbol. ID2SYM(rb_intern("my_
symbol")); // Convert
• Symbols in Ruby are symbol name to Symbol
immutable identifiers (cannot value
if
be changed once created) (SYMBOL_P(my_value))
{
often used as keys in hashes // my_value is a Symbol
and for naming things like } else {
// my_value is not a
methods and variables. Symbol
}
• The macro returns a non-zero
value if value is a Symbol, and
zero otherwise.
SYMBOL_P(value)
• This macro checks if the given
VALUE my_value =
value is a Symbol. ID2SYM(rb_intern("my_
symbol")); // Convert
• Symbols in Ruby are symbol name to Symbol
immutable identifiers (cannot value
if
be changed once created) (SYMBOL_P(my_value))
{
often used as keys in hashes // my_value is a Symbol
and for naming things like } else {
// my_value is not a
methods and variables. Symbol
}
• The macro returns a non-zero
value if value is a Symbol, and
zero otherwise.
NIL_P(value)

VALUE my_value = Qnil;


// Assign nil value
if (NIL_P(my_value)) {
// my_value is nil
}
else {
// my_value is not nil
}
RTEST(value)
• This macro checks if the VALUE my_value =
given value is neither nil nor Qtrue;
false. // Assign true value
if (RTEST(my_value)) {
• In Ruby, any value other // my_value is true
than nil and false is }
considered true in a boolean else {
// my_value is false or
context. nil
• The macro returns a non- }
zero value if value is neither
nil nor false, and zero
otherwise.
C/Ruby data type conversion functions
and macros
C/Ruby data type conversion
functions and macros
Working with immediate values

• Fixnums and a few other special types (symbols,


true/false/nil, floats?) are assigned as immediate
values.
• Instead of storing a pointer (or reference) to the
value object, the variable stores the value
directly.
• So in a=4 ‘a’ does not hold a reference, but rather
the immediate value 4.
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.
Working with Strings
• The structure can be accessed via the
RSTRING macro.

VALUE str;
RSTRING(str)->len #length of the Ruby string
RSTRING(str)->ptr #pointer to string storage
Working with Strings
• When a string value is needed, call the
method StringValue, passing it the
original value.
• The StringValue method checks to see if
its operand is a String.
• If not, it tries to invoke to_str on the
object, throwing a TypeError 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.
Working with other objects
• To see what type of structure is used for a
particular VALUE , use
TYPE(obj)
• The macro TYPE(obj) will return a constant
representing the C type of the
given object: T_OBJECT, T_STRING, and so
on.
Working with other objects
• To ensure that a VALUE pointer points to a
particular structure, use the macro
Check_Type, which will raise a TypeError
exception if value is not of the expected
type.

Check_Type(VALUE value, int type)


Working with other objects
• To ensure that a VALUE pointer points to a
particular structure, use the macro
Check_Type, which will raise a TypeError
exception if value is not of the expected
type.

Check_Type(VALUE value, int type)


CS513PE DATA ANALYTICS

UNIT II
THE JUKEBOX
EXTENSION
Dr.D.Magdalene Delighta
Angeline
III CSE
Associate Professor-CSE
JBREC
What is Jukebox?
• Jukebox is a component to handle the
playback of music and sound effects across
multiple web browsers and operating
systems.
• The jukebox will consist of a client and a
server.
Jukebox - Client
• A client can query the jukebox, stop or
restart it, or request that a particular song
be played.
• The jukebox will keep requests in a queue.
• Once it plays all the requests, it will resume
playing songs at random.
Jukebox - Server
• The server broadcasts its location to a
nearby Rinda server so clients on the local
network can find it without knowing the
address.
• The client will look up the server with Rinda
and then communicate with it via DRb
(Distributed Ruby).
Wrapping C Structures
The vendor’s header file looks like
this. // Deallocate when done (and
typedef struct _cdjb { take offline)
int statusf; void free_jukebox(CDJukebox
int request; *jb);
void *data; // Seek to a disc, track and
char pending; notify progress
int unit_id; void jukebox_seek(CDJukebox
void *stats; *jb,
} CDJukebox; int disc,
// Allocate a new CDJukebox int track,
structure void (*done)(CDJukebox *jb,
CDJukebox *new_jukebox(void); int percent));
// Assign the Jukebox to a player // ... others...
void assign_jukebox(CDJukebox // Report a statistic
*jb, int unit_id); double
get_avg_seek_time(CDJukebo
x *jb);
API: C Data Type Wrapping
VALUE Data_Wrap_Struct( VALUE class, void (*mark)(),
void (*free)(), void *ptr )
Wraps the given C data type ptr, registers the two garbage
collection
routines (see below), and returns a VALUE pointer to a genuine
Ruby
object. The C type of the resulting object is T_DATA, and its Ruby
class is class.
VALUE Data_Make_Struct( VALUE class, c-type, void (*mark)(),
void (*free)(), c-type * )
Allocates and sets to zero a structure of the indicated type first
and
then proceeds as Data_Wrap_Struct. c-type is the name of the C
data type that you’re wrapping, not a variable of that type.
Data_Get_Struct( VALUE obj,c-type,c-type * )
Returns the original pointer. This macro is a type-safe wrapper
around the macro DATA_PTR(obj), which evaluates the pointer.
API: C Data Type Wrapping
• The object created by Data_Wrap_Struct
is a normal Ruby object.
• C data type is separate from any instance
variables that the object contains.
• Ruby uses a mark and sweep garbage
collection scheme.
• During the mark phase, Ruby looks for
pointers to areas of memory.
Ruby – Mark Phase
• During the mark phase, Ruby looks for
pointers to areas of memory.
• It marks these areas as “in use” (because
something is pointing to them). If those
areas themselves contain more pointers,
the memory these pointers reference is
also marked, and so on.
• At the end of the mark phase, all
memory that is referenced will have
been marked, and any orphaned areas
(no reference) will not have a mark.
Wrapping Objects around C data types
Ruby – Sweep Phase
• At this point the sweep phase starts,
freeing off memory that isn’t marked.
Ruby – Mark and Sweep Collection
Scheme
• To participate in Ruby’s mark-and-sweep garbage
collection process, define a routine to free the
structure and possibly a routine to mark any
references from the structure to other structures.
• Both routines take a void pointer, a reference to your
structure.
• The mark routine will be called by the garbage
collector during its “mark” phase.
• If the structure references other Ruby objects, then
your mark function needs to identify these objects
using rb_gc_mark(value).
• If the structure doesn’t reference other Ruby objects,
you can simply pass 0 as a function pointer.
Ruby – Mark and Sweep Collection
Scheme
• When the object needs to be disposed of, the
garbage collector will call the free routine to
free it.
• If you have allocated any memory, need to pass
a free function—even if it’s just the standard C
library’s free routine.
• For complex structures that you have allocated,
free function may need to traverse the
structure to free all the allocated memory.
Example -CD player interface
• The vendor library passes the information around
between its various functions in a CDJukebox
structure.
• This structure represents the state of the jukebox
and therefore is a good candidate for wrapping
within Ruby class.

• CDJukebox *jukebox;
VALUE obj;
// Vendor library creates the Jukebox
jukebox = new_jukebox();
// then we wrap it inside a Ruby CDPlayer object
obj = Data_Wrap_Struct(klass, 0, cd_free, jukebox);
Example -CD player interface
• Once this code had executed, obj would hold a
reference to a newly allocated CDPlayer
Ruby object, wrapping a new CDJukebox C
structure.
• Define the CDPlayer class and store a reference
to it in the variable cCDPlayer.
• Define the function to free off our object,
cdplayer_free.

static void cd_free(void *p) {


free_jukebox(p);
}
Object Creation
• The interpreter calls the class method new for
CDPlayer.
• new in class Class it allocates memory for the
new object and then calls the object’s initialize
method to initialize that memory

cd = CDPlayer.new
Allocation Functions
• The allocation function is responsible for creating the
memory used by object.
• The allocation function gets passed the class of
theobject being allocated. In our case it will in all
likelihood be a cCDPlayer.

static VALUE cd_alloc(VALUE klass) {


CDJukebox *jukebox;
VALUE obj;
// Vendor library creates the Jukebox
jukebox = new_jukebox();
// then we wrap it inside a Ruby CDPlayer object
obj = Data_Wrap_Struct(klass, 0, cd_free, jukebox);
return obj;
}
Allocation Functions
void Init_CDPlayer() {
cCDPlayer = rb_define_class("CDPlayer",
rb_cObject);
rb_define_alloc_func(cCDPlayer,
cd_alloc);
// ...
}
The allocation function creates an empty,
uninitialized object.
Allocation Functions
static VALUE cd_initialize(VALUE self, VALUE
unit) {
int unit_id;
CDJukebox *jb;
Data_Get_Struct(self, CDJukebox, jb);
unit_id = NUM2INT(unit);
assign_jukebox(jb, unit_id);
return self;
}
Cloning Objects
• All Ruby objects can be copied using one of
two methods,
– dup
– clone
• The two methods are similar: Both produce a
new instance of their receiver’s class by calling
the allocation function.
• Then they copy across any instance variables
from the original
Clone Method
• Clone is used to duplicate an object, including
its internal state.
• Shallow copy: references to other objects/
values are copied (instead of cloning those
objects/values)
• Clones the object and all its "special object
attributes" like frozen, tainted and modules
that the object has been extended with.
• Clone as being a copy of the full object
dup Method
• Dup duplicates the object leaving the original
object untouched.
• Shallow copy: references to other objects/values
are copied (instead of cloning those
objects/values)
• Clones the object, but ignores "special object
attributes" like frozen, tainted and modules that
the object has been extended with.
• dup as being a copy of the contents
Example
#include "ruby.h"
#include "cdjukebox.h"
static VALUE cCDPlayer;
// Helper function to free a vendor CDJukebox
static void cd_free(void *p) {
free_jukebox(p);
}
// Allocate a new CDPlayer object, wrapping
// the vendor's CDJukebox structure
static VALUE cd_alloc(VALUE klass) {
CDJukebox *jukebox;
VALUE obj;
// Vendor library creates the Jukebox
jukebox = new_jukebox();
// then we wrap it inside a Ruby CDPlayer object
obj = Data_Wrap_Struct(klass, 0, cd_free, jukebox);
return obj;
}
Example
// Assign the newly created CDPLayer to a
// particular unit
static VALUE cd_initialize(VALUE self, VALUE
unit) {
int unit_id;
CDJukebox *jb;
Data_Get_Struct(self, CDJukebox, jb);
unit_id = NUM2INT(unit);
assign_jukebox(jb, unit_id);
return self;
}
Example
// Copy across state (used by clone and dup). For jukeboxes, we
// actually create a new vendor object and set its unit number from
// the old
static VALUE cd_init_copy(VALUE copy, VALUE orig) {
CDJukebox *orig_jb;
CDJukebox *copy_jb;
if (copy == orig)
return copy;
// we can initialize the copy from other CDPlayers or their
// subclasses only
if (TYPE(orig) != T_DATA ||
RDATA(orig)->dfree != (RUBY_DATA_FUNC)cd_free) {
rb_raise(rb_eTypeError, "wrong argument type");
}
// copy all the fields from the original object's CDJukebox
// structure to the new object
Data_Get_Struct(orig, CDJukebox, orig_jb);
Data_Get_Struct(copy, CDJukebox, copy_jb);
MEMCPY(copy_jb, orig_jb, CDJukebox, 1);
return copy;
}
Example
// The progress callback yields to the caller the percent complete
static void progress(CDJukebox *rec, int percent) {
if (rb_block_given_p()) {
if (percent > 100) percent = 100;
if (percent < 0) percent = 0;
rb_yield(INT2FIX(percent));
}
}
// Seek to a given part of the track, invoking the progress callback
// as we go
static VALUE
cd_seek(VALUE self, VALUE disc, VALUE track) {
CDJukebox *jb;
Data_Get_Struct(self, CDJukebox, jb);
jukebox_seek(jb,
NUM2INT(disc),
NUM2INT(track),
progress);
return Qnil;
}
Example
// Return the average seek time for this unit
static VALUE
cd_seek_time(VALUE self)
{
double tm;
CDJukebox *jb;
Data_Get_Struct(self, CDJukebox, jb);
tm = get_avg_seek_time(jb);
return rb_float_new(tm);
}
// Return this player's unit number
static VALUE
cd_unit(VALUE self) {
CDJukebox *jb;
Data_Get_Struct(self, CDJukebox, jb);
return INT2NUM(jb->unit_id);
}
Example
void Init_CDPlayer() {
cCDPlayer = rb_define_class("CDPlayer",
rb_cObject);
rb_define_alloc_func(cCDPlayer, cd_alloc);
rb_define_method(cCDPlayer, "initialize",
cd_initialize, 1);
rb_define_method(cCDPlayer, "initialize_copy",
cd_init_copy, 1);
rb_define_method(cCDPlayer, "seek", cd_seek,
2);
rb_define_method(cCDPlayer, "seek_time",
cd_seek_time, 0);
rb_define_method(cCDPlayer, "unit", cd_unit, 0);
}
Example
require 'CDPlayer'
p = CDPlayer.new(13)
puts "Unit is #{p.unit}"
p.seek(3, 16) {|x| puts "#{x}% done" }
puts "Avg. time was #{p.seek_time}
seconds"
p1 = p.dup
puts "Cloned unit = #{p1.unit}"
OUTPUT
Unit is 13
26% done
79% done
100% done
Avg. time was 1.2 seconds
Cloned unit = 13
CS513PE DATA ANALYTICS

UNIT II
MEMORY
ALLOCATION
Dr.D.Magdalene Delighta
Angeline
III CSE
Associate Professor-CSE
JBREC
Memory Allocation
• In ruby, sometimes it is necessary to allocate
memory in an extension that won't be used
for object storage.
• In order to work correctly with the garbage
collector, the memory allocation routines to
be used.
• For instance, if ALLOC_N determines that it
cannot allocate the desired amount of
memory, it will invoke the garbage collector
to try to reclaim some space.
• It will raise a NoMemError if it can't or if the
requested amount of memory is invalid.
API:Memory Allocation
type * ALLOC_N( c-type, n )
Allocates n c-type objects, where c-type is the
literal name of the C type, not a variable of that
type.
type * ALLOC( c-type )
Allocates a c-type and casts the result to a
pointer of that type.
REALLOC_N( var, c-type, n )
Reallocates n c-types and assigns the result to
var, a pointer to a variable of type c-type.
type * ALLOCA_N( c-type, n )
Allocates memory for n objects of c-type on the
stack—this memory will be automatically freed when
the function that invokes ALLOCA_N returns.
CS513PE DATA ANALYTICS

UNIT II
Ruby Type
System
Dr.D.Magdalene Delighta
Angeline
III CSE
Associate Professor-CSE
JBREC
Ruby Type System
• In Ruby, we rely less on the type (or
class) of an object and more on its
capabilities. This is called duck typing.
Ruby Type System
VALUE if (argc == 1 && prog == 0) {
rb_f_exec(argc, argv) VALUE cmd = argv[0];
int argc;
VALUE *argv; SafeStringValue(cmd);
{ rb_proc_exec(RSTRING(cm
VALUE prog = 0; d)->ptr);
VALUE tmp; }
if (argc == 0) {
rb_raise(rb_eArgError, "wrong else {
number of arguments"); proc_exec_n(argc, argv,
} prog);
tmp = }
rb_check_array_type(argv[0]);
if (!NIL_P(tmp)) { rb_sys_fail(RSTRING(argv[0
if (RARRAY(tmp)->len != 2) { ])->ptr);
rb_raise(rb_eArgError, "wrong first return Qnil; /* dummy */
argument"); }
}
prog = RARRAY(tmp)->ptr[0];
SafeStringValue(prog);
argv[0] = RARRAY(tmp)->ptr[1];
}
Ruby Type System
VALUE if (TYPE(val) == type && type
rb_check_array_type(ary) != T_DATA) return val;
VALUE ary; v = convert_type(val, tname,
{ method, Qfalse);
return rb_check_convert_type(ary, if (NIL_P(v)) return Qnil;
T_ARRAY, "Array", "to_ary"); if (TYPE(v) != type) {
} rb_raise(rb_eTypeError,
The plot thickens. Let’s track down "%s#%s should return %s",
rb_check_convert_type.
VALUE
rb_obj_classname(val),
rb_check_convert_type(val, type,
method, tname);
tname, method) }
VALUE val; return v;
int type; }
const char *tname, *method;
{
VALUE v;
/* always convert T_DATA */
Embedding Ruby Interpreter
• The interpreter take control by calling
ruby_run.
• Drawback: The interpreter never returns
from a ruby_run call.
Example
#include "ruby.h"
int main(void) {
/* ... our own application stuff ... */
ruby_init();
ruby_init_loadpath();
ruby_script("embedded");
rb_load_file("start.rb");
ruby_run();
exit(0);
}
Embedding Ruby Interpreter
• To initialize the Ruby interpreter, you
need to call ruby_init().
#if defined(NT)
NtInitialize(&argc, &argv);
#endif
#if defined(__MACOS__) &&
defined(__MWERKS__)
argc = ccommand(&argv);
#endif
Embedding Ruby Interpreter
• The second way of embedding Ruby allows
Ruby code and C code to engage in more of a
dialogue: the C code calls some Ruby code,
and the Ruby code responds.
• This can be done by initializing the
interpreter as normal.
• Then, rather than entering the interpreter’s
main loop, invoke specific methods in your
Ruby code.
• When these methods return, your C code
gets control back.
Embedding Ruby Interpreter
• If the Ruby code raises an exception and it
isn’t caught, C program will terminate.
• To overcome this, need to do what the
interpreter does and protect all calls that
could raise an exception.
• The rb_protect method call wraps the call to
another C function.
• That second function should invoke Ruby
method.
• However, the method wrapped by
rb_protect is defined to take just a single
parameter.
Example
class Summer
def sum(max)
raise "Invalid maximum #{max}" if max < 0
(max*max + max)/2
end
end
API: Embedded Ruby API
void ruby_init( )
Sets up and initializes the interpreter. This function should be called
before any other Ruby-related functions.
void ruby_init_loadpath( )
Initializes the $: (load path) variable; necessary if your code loads
any library modules.
void ruby_options( int argc, char **argv )
Gives the Ruby interpreter the command-line options.
void ruby_script( char *name )
Sets the name of the Ruby script (and $0) to name.
void rb_load_file( char *file )
Loads the given file into the interpreter.
void ruby_run( )
Runs the interpreter.
void ruby_finalize( )
Shuts down the interpreter
Embedding Ruby to Other Languages
• Compared to other dynamic languages,
its pretty easy to write C extensions in
Ruby.
• The interfaces are easy to use and clearly
defined in just a few header files, there
are numerous examples available in the
Ruby standard library itself, and there are
even tools that can help you access C
libraries without writing any C code at all.
Embedding Ruby to Other Languages
• Ruby interpreter, runs atop the Java
Virtual Machine and uses Java classes as
though they were Ruby classes.
Ruby C Language API
• C-level functions that you may find useful
when writing an extension.
• At or near the bottom of each source file
is a set of method definitions that
describe the binding from Ruby methods
to C functions.
• C function can be called directly, or
search for a wrapper function that calls
the function you are looking for.
Ruby C Language API
• The following list, based on the list
in README.EXT, shows the main source files in
the interpreter.
• Ruby Language Core
– class.c error.c eval.c gc.c object.c parse.y variable.c
• Utility Functions
– dln.c regex.c st.c util.c
• Ruby Interpreter
– dmyext.c inits.c keywords main.c ruby.c version.c
• Base Library
– array.c bignum.c compar.c dir.c enum.c file.c hash.c io.c
marshal.c math.c numeric.c pack.c prec.c process.c random.c
range.c re.c signal.c sprintf.c string.c struct.c time.c
Ruby C Language API
Defining Objects
VALUE rb_define_class(char *name, VALUE superclass")
Defines a new class at the top level with the given name and superclass (for
class Object, use rb_cObject).
VALUE rb_define_module(char *name")

Defines a new module at the top level with the given name.

VALUE rb_define_class_under(VALUE under, char *name, VALUE superclass")

Defines a nested class under the class or module under.


VALUE rb_define_module_under(VALUE under, char *name")
Defines a nested module under the class or module under.
void rb_include_module(VALUE parent, VALUE module")
Includes the given module into the class or module parent.
void rb_extend_object(VALUE obj, VALUE module")
Extends obj with module.
VALUE rb_require(const char *name")

Equivalent to ``require name.'' Returns Qtrue or Qfalse.


Ruby C Language API

argc Function prototype


0..17 VALUE func(VALUE self, VALUE arg...)

The C function will be called with this many actual


arguments.

-1 VALUE func(int argc, VALUE *argv, VALUE self)

The C function will be given a variable number of arguments


passed as a C array.

-2 VALUE func(VALUE self, VALUE args)

The C function will be given a variable number of arguments


passed as a Ruby array.
Ruby C Language API
Defining Methods
void rb_define_method(VALUE classmod, char *name, VALUE(*func)(), int argc")
Defines an instance method in the class or module classmod with the given name, implemented by the C
function func and taking argc arguments.
void rb_define_module_function(VALUE classmod, char *name, VALUE(*func)(), int argc)")
Defines a method in class classmod with the given name, implemented by the C function func and
taking argc arguments.
void rb_define_global_function(char *name, VALUE(*func)(), int argc")
Defines a global function (a private method of Kernel) with the given name, implemented by the C
function func and taking argc arguments.
void rb_define_singleton_method(VALUE classmod, char *name, VALUE(*func)(), int argc")
Defines a singleton method in class classmod with the given name, implemented by the C
function func and taking argc arguments.
int rb_scan_args(int argcount, VALUE *argv, char *fmt, ...")
Scans the argument list and assigns to variables similar to scanf: fmt is a string containing zero, one, or two
digits followed by some flag characters. The first digit indicates the count of mandatory arguments; the
second is the count of optional arguments. A ``*'' means to pack the rest of the arguments into a Ruby
array. A ``&'' means that an attached code block will be taken and assigned to the given variable (if no
code block was given, Qnil will be assigned). After the fmt string, pointers to VALUE are given (as
with scanf) to which the arguments are assigned.
VALUE name, one, two, rest; rb_scan_args(argc, argv, "12", &name, &one, &two);
rb_scan_args(argc, argv, "1*", &name, &rest);
void rb_undef_method(VALUE classmod, const char *name")
Undefines the given method name in the given classmod class or module.
void rb_define_alias(VALUE classmod, const char *newname, const char *oldname")
Defines an alias for oldname in class or module classmod.
Ruby C Language API
Defining Variables and Constants
void rb_define_const(VALUE classmod, char *name, VALUE value")
Defines a constant in the class or module classmod, with the given name and value.
void rb_define_global_const(char *name, VALUE value")
Defines a global constant with the given name and value.
void rb_define_variable(const char *name, VALUE *object")
Exports the address of the given object that was created in C to the Ruby namespace as name. From Ruby, this will be a global variable,
so name should start with a leading dollar sign. Be sure to honor Ruby's rules for allowed variable names; illegally named variables will
not be accessible from Ruby.

void rb_define_class_variable(VALUE class, const char *name, VALUE val")


Defines a class variable name (which must be specified with a ``@@'' prefix) in the given class, initialized to value.
void rb_define_virtual_variable(const char *name, VALUE(*getter)(), void(*setter)()")
Exports a virtual variable to Ruby namespace as the global $name. No actual storage exists for the variable; attempts to get and set the
value will call the given functions with the prototypes:
VALUE getter(ID id, VALUE *data, struct global_entry *entry);
void setter(VALUE value, ID id, VALUE *data, struct global_entry *entry); You will likely not need to use the entry parameter and
can safely omit it from your function declarations.

void rb_define_hooked_variable(const char *name, VALUE *variable, VALUE(*getter)(), void(*setter)()")


Defines functions to be called when reading or writing to variable. See also rb_define_virtual_variable.
void rb_define_readonly_variable(const char *name, VALUE *value")
Same as rb_define_variable, but read-only from Ruby.
void rb_define_attr(VALUE variable, const char *name, int read, int write")
Creates accessor methods for the given variable, with the given name. If read is nonzero, create a read method; if write is nonzero,
create a write method.
void rb_global_variable(VALUE *obj")
Registers the given address with the garbage collector.
Ruby C Language API
Calling Methods
VALUE rb_funcall(VALUE recv, ID id, int argc, ...")
Invokes the method given by id in the object recv with the given
number of arguments argc and the arguments themselves (possibly
none).
VALUE rb_funcall2(VALUE recv, ID id, int argc, VALUE *args")
Invokes the method given by id in the object recv with the given
number of arguments argc and the arguments themselves given in
the C array args.
VALUE rb_funcall3(VALUE recv, ID id, int argc, VALUE *args")
Same as rb_funcall2, but will not call private methods.
VALUE rb_apply(VALUE recv, ID name, int argc, VALUE args")
Invokes the method given by id in the object recv with the given
number of arguments argc and the arguments themselves given in
the Ruby Array args.
ID rb_intern(char *name")
Returns an ID for a given name. If the name does not exist, a symbol
table entry will be created for it.
char * rb_id2name(ID id")
Returns a name for the given id.
VALUE rb_call_super(int argc, VALUE *args")
Calls the current method in the superclass of the current object.
Ruby C Language API
Exceptions
void rb_raise(VALUE exception, const char *fmt, ...")
Raises an exception. The given string fmt and remaining arguments are interpreted as with printf.
void rb_fatal(const char *fmt, ...")
Raises a Fatal exception, terminating the process. No rescue blocks are called, but ensure blocks will be called. The given
string fmt and remaining arguments are interpreted as with printf.
void rb_bug(const char *fmt, ...")
Terminates the process immediately---no handlers of any sort will be called. The given string fmt and remaining arguments are
interpreted as with printf. You should call this function only if a fatal bug has been exposed. You don't write fatal bugs, do you?
void rb_sys_fail(const char *msg")
Raises a platform-specific exception corresponding to the last known system error, with the given msg.
VALUE rb_rescue(VALUE (*body)(), VALUE args, VALUE(*rescue)(), VALUE rargs")
Executes body with the given args. If a StandardError exception is raised, then execute rescue with the given rargs.
VALUE rb_ensure(VALUE(*body)(), VALUE args, VALUE(*ensure)(), VALUE eargs")
Executes body with the given args. Whether or not an exception is raised, execute ensure with the given rargs after body has
completed.
VALUE rb_protect(VALUE (*body)(), VALUE args, int *result")
Executes body with the given args and returns nonzero in result if any exception was raised.
void rb_notimplement(")
Raises a NotImpError exception to indicate that the enclosed function is not implemented yet, or not available on this platform.
void rb_exit(int status")
Exits Ruby with the given status. Raises a SystemExit exception and calls registered exit functions and finalizers.
void rb_warn(const char *fmt, ...")
Unconditionally issues a warning message to standard error. The given string fmt and remaining arguments are interpreted as
with printf.
void rb_warning(const char *fmt, ...")
Conditionally issues a warning message to standard error if Ruby was invoked with the -w flag. The given string fmt and remaining
arguments are interpreted as with printf.
Ruby C Language API
Accessing Variables
VALUE rb_iv_get(VALUE obj, char *name")
Returns the instance variable name (which must be specified with a ``@'' prefix) from the given obj.
VALUE rb_ivar_get(VALUE obj, ID name")
Returns the instance variable name from the given obj.
VALUE rb_iv_set(VALUE obj, char *name, VALUE value")
Sets the value of the instance variable name (which must be specified with a ``@'' prefix) in the
given obj to value. Returns value.
VALUE rb_ivar_set(VALUE obj, ID name, VALUE value")
Sets the value of the instance variable name in the given obj to value. Returns value.
VALUE rb_gv_set(const char *name, VALUE value")
Sets the global variable name (the ``$'' prefix is optional) to value. Returns value.
VALUE rb_gv_get(const char *name")
Returns the global variable name (the ``$'' prefix is optional).
void rb_cvar_set(VALUE class, ID name, VALUE val")
Sets the class variable name in the given class to value.
VALUE rb_cvar_get(VALUE class, ID name")
Returns the class variable name from the given class.
int rb_cvar_defined(VALUE class, ID name")
Returns Qtrue if the given class variable name has been defined for class; otherwise, returns Qfalse.
void rb_cv_set(VALUE class, const char *name, VALUE val")
Sets the class variable name (which must be specified with a ``@@'' prefix) in the given class to value.
VALUE rb_cv_get(VALUE class, const char *name")
Returns the class variable name (which must be specified with a ``@@'' prefix) from the given class.
Ruby C Language API
Object Status
OBJ_TAINT(VALUE obj")
Marks the given obj as tainted.
int OBJ_TAINTED(VALUE obj")
Returns nonzero if the given obj is tainted.
OBJ_FREEZE(VALUE obj")
Marks the given obj as frozen.
int OBJ_FROZEN(VALUE obj")
Returns nonzero if the given obj is frozen.
Check_SafeStr(VALUE str")

Raises SecurityError if current safe level > 0 and str is tainted, or a TypeError if str is not
a T_STRING.

int rb_safe_level(")
Returns the current safe level.
void rb_secure(int level")
Raises SecurityError if level <= current safe level.
void rb_set_safe_level(int newlevel")
Sets the current safe level to newlevel.
Ruby C Language API
Commonly Used Methods
VALUE rb_ary_new(")
Returns a new Array with default size.
VALUE rb_ary_new2(long length")
Returns a new Array of the given length.
VALUE rb_ary_new3(long length, ...")
Returns a new Array of the given length and populated with the remaining arguments.
VALUE rb_ary_new4(long length, VALUE *values")
Returns a new Array of the given length and populated with the C array values.
void rb_ary_store(VALUE self, long index, VALUE value")
Stores value at index in array self.
VALUE rb_ary_push(VALUE self, VALUE value")
Pushes value onto the end of array self. Returns value.
VALUE rb_ary_pop(VALUE self")
Removes and returns the last element from the array self.
VALUE rb_ary_shift(VALUE self")
Removes and returns the first element from the array self.
VALUE rb_ary_unshift(VALUE self, VALUE value")
Pushes value onto the front of array self. Returns value.
VALUE rb_ary_entry(VALUE self, long index")
Returns array self's element at index.
int rb_respond_to(VALUE self, ID method")
Returns nonzero if self responds to method.
VALUE rb_thread_create(VALUE (*func)(), void *data")
Runs func in a new thread, passing data as an argument.
Ruby C Language API
Commonly Used Methods
VALUE rb_hash_new(")
Returns a new, empty Hash.
VALUE rb_hash_aref(VALUE self, VALUE key")
Returns the element corresponding to key in self.
VALUE rb_hash_aset(VALUE self, VALUE key, VALUE value")
Sets the value for key to value in self. Returns value.
VALUE rb_obj_is_instance_of(VALUE obj, VALUE klass")
Returns Qtrue if obj is an instance of klass.
VALUE rb_obj_is_kind_of(VALUE obj, VALUE klass")
Returns Qtrue if klass is the class of obj or class is one of the superclasses of the class of obj.
VALUE rb_str_new(const char *src, long length")
Returns a new String initialized with length characters from src.
VALUE rb_str_new2(const char *src")
Returns a new String initialized with the null-terminated C string src.
VALUE rb_str_dup(VALUE str")
Returns a new String object duplicated from str.
VALUE rb_str_cat(VALUE self, const char *src, long length")
Concatenates length characters from src onto the String self. Returns self.
VALUE rb_str_concat(VALUE self, VALUE other")
Concatenates other onto the String self. Returns self.
VALUE rb_str_split(VALUE self, const char *delim")
Returns an array of String objects created by splitting self on delim.

You might also like