[go: up one dir, main page]

0% found this document useful (0 votes)
31 views23 pages

S.L Unit - 2

The document discusses extending Ruby with C, detailing how to create C extensions, manage Ruby objects in C, and interact with Ruby's type system. It provides a step-by-step guide for creating a C extension, including writing methods, handling memory allocation, and manipulating Ruby objects. Additionally, it covers the creation of a Jukebox extension and demonstrates wrapping C structures for use in Ruby applications.

Uploaded by

triveni k
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)
31 views23 pages

S.L Unit - 2

The document discusses extending Ruby with C, detailing how to create C extensions, manage Ruby objects in C, and interact with Ruby's type system. It provides a step-by-step guide for creating a C extension, including writing methods, handling memory allocation, and manipulating Ruby objects. Additionally, it covers the creation of a Jukebox extension and demonstrates wrapping C structures for use in Ruby applications.

Uploaded by

triveni k
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/ 23

1

Exten Extending Ruby

UNIT_II

Extending Ruby:- Ruby Objects in C, - the Jukebox extension, Memory


allocation, -Ruby Type System, -Embedding Ruby to Other Languages,
-Embedding a Ruby Interpreter
Ruby

⇒ Ruby is a object-oriented, reflective, general-propose, dynamic priagramoning


Language.

⇒ Ruby was developed to make it aet as a sensild, buffer b/w human programmers & the
underling, computing machinery.

→ It is an interpreted scripting language which means most of its implementations execute


instructions directly & freely, without previously compiling a program into machine
language instructions.

⇒ Ruby is used to create web applications of different. sorts.

1. Extending Ruby: -

→ It is easy to extend Ruby with new features by Writing code in Ruby. Once you, start
adding in low-level code written in C, however the possibilities are endless.

Ruby objects in 𝑪:

→ Everything in Ruby is an object, and all variables are references to objects.

→ Most Ruby objects are represented as (pointers to an area in memory that contains the
objects data of often implementation detail e.

→ In C code, all twee references are via variables of type value, so when you pass Ruby
objects around, you’ll do it by passing values.
→ This has one exception. For performance reasons. Ruby implements fixnums, symbols,
true, false and rill as so. called immediate values.

Creating an Extension:
1. Create the C source code file(s) in a given directory.
2. Create extconf. rb .
3. Run extconf. rb to create a Makefile for the C files in this directory.
4. Run make .
5. Run make install .

Writing a C extension allows you to interact with Ruby from C.

Mr. AZMEERA RAMESH (ASSIT. PROF), CMRTC


2
Exten Extending Ruby

 You may want to this if there is a particular important method you would like to
optimize with the speed of C, or if you would like to create an interface between a
C library and Ruby.

 An alternative would be to use the FFI module. Your First C Extension

Our First C Extension


 Create a file named extconf.rb with these contents:

 require 'mkmf'
 create_header
 create_makefile 'foobar'
 Then run ruby extconf.rb which will create a few files for you (Makefile &
extconf.h). Don’t change these files.

 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.

 Inside foobar.c you add this:

#include "ruby.h"
#include "extconf.h"
void Init_foobar()
{
// Your C code goes here
}
 This is the basic skeleton of your C extension. Notice that you have to use the name
you declared on extconf.rb plus the word Init_. In this case Init_foobar.

Writing A Ruby Method from C


 You can create c functions that you can call from your Ruby code. This is how
built-in classes & methods work.
 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.
Creating a module:

Mr. AZMEERA RAMESH (ASSIT. PROF), CMRTC


3
Exten Extending Ruby

void Init_foobar() {
VALUE mod = rb_define_module("RubyGuides");
rb_define_method(mod, "return_nil", rb_return_nil, 0);
}
 You can use the rb_define_method method to attach the C function to this
module.

Now run make again to compile the extension, and try it like this:

require 'foobar'
include RubyGuides
print_hello
There you go, you just called a C function from Ruby!

Creating a Ruby Hash from C


 Often you will want to create & manipulate Ruby objects from C.
 You can do that using the C API.
 For example, to create a hash & add some elements to it:
VALUE create_hash() {
hash = rb_hash_new();
rb_hash_aset(hash, rb_str_new2("test"), INT2FIX(1));
return hash;
}
 Two important things to notice here, first the rb_str_new2 function, this creates
a Ruby string.
 Then the INT2FIX macro, this converts a regular integer into a Ruby integer.

Mr. AZMEERA RAMESH (ASSIT. PROF), CMRTC


4
Exten Extending Ruby

 Now if you expose this function to Ruby using rb_define_method you will get
a regular Ruby hash with one key (test) & a value of 1.
 Don’t forget to recompile your extension every time you make changes.
Working with Strings
Your C functions can also take parameters.

For example:
VALUE rb_print_length(VALUE self, VALUE str) {
if (RB_TYPE_P(str, T_STRING) == 1) {
return rb_sprintf("String length: %ld", RSTRING_LEN(str));
}
return Qnil;
}
void Init_foobar()
{
rb_define_global_function("print_length", rb_print_length, 1);
}
 Here we are taking a VALUE (ruby object) as an argument & then we make sure
it’s a string with the RB_TYPE_P macro. After that, we just print the string length
using the RSTRING_LEN macro.
 If you want a pointer to the string data you can use the RSTRING_PTR macro.
Example:
VALUE rb_print_data(VALUE self, VALUE str) {
if (RB_TYPE_P(str, T_STRING) == 1) {
return rb_sprintf("String length: %s", RSTRING_LEN(str));
}
return Qnil;
}
 Also notice how there is another parameter here, self, this is the object receiving
the method call.
 If you want to define this method on the String class itself you would do it like this:
void Init_foobar()
{
rb_define_method(rb_cString, "print_length", rb_print_length, 0);
}
Working With Immediate Object: -

FINUM- 𝑃 (value) → Non-zero if value is a fixnum

SYMBOL - 𝑃 (value) → non - zero if value is a symbol.

Mr. AZMEERA RAMESH (ASSIT. PROF), CMRTC


5
Exten Extending Ruby

NIL - P (value) → Non-zero if value is nit

RTEST (value) → nonzero if Value if neither nil nor false.

Working with in Strings: -

 In 𝑐, we are used to working with a null-terminated string, Ruby strings, how war,
are more general a may well include embedded nulls.
 Ruby string objects are actually references to an RString structure, & the Restring
structure contains both a length and pointer field. We can access the structure via
live Restring macros.
INT 2 NUM (int) → Fixnum or Bignum

INT 2 FIX (int) → Fixnum (faster)

rb_str_new2 (char*) → String

𝑐 datatype to ruby objects.

RSTRING-LEN(str) → lengths of the Ruby string

RSTRING - PTR (str) → Pointers to string storage.

RSTRING - END (str) → Pointer to end of string.

Working with other Objects:-

 When Values are not immediate, they are pointers to one of the predefined Ruby
object structures.
 The structures for the basic built-in-classes are defined in ruby is & are named
RClassnames.
RArray, RBignum, RClass, RData, Rile, RFloat, RHash, Rbject, R Regexp, Resting &
Retract.

Different Ruby in ‘C’.

Ruby:

 Description: Ruby is a dynamic, object-oriented programming language designed


for simplicity and productivity. It has a clean syntax and supports multiple
programming paradigms, including procedural, object-oriented, and functional
programming.
 Implementation: The standard and most widely used implementation of Ruby is
called Matz's Ruby Interpreter (MRI), which is written in C.

C:

Mr. AZMEERA RAMESH (ASSIT. PROF), CMRTC


6
Exten Extending Ruby

 Description: C is a general-purpose, procedural programming language that has


influenced many other languages, including Ruby. It is known for its efficiency,
low-level access to memory, and versatility.
 Relation to Ruby: The original and most widely used implementation of Ruby
(MRI) is written in C. This means that the core of the Ruby language is
implemented in C for performance reasons. The C implementation provides a
bridge between the high-level Ruby language and the underlying system, allowing
Ruby code to interact with the system at a lower level.
 When people talk about "Ruby in C," they might be referring to the fact that the
Ruby interpreter itself is written in C. This implementation choice allows Ruby to
achieve a balance between high-level abstractions and low-level system
interactions.
 If you have a more specific question or if there's a particular aspect of Ruby or C
you'd like to know more about, please provide additional details so I can offer more
targeted information.
2. The JukeBOX Extension:

 Jukebox example -interfacing C code with Ruby.


and shaving data and behavior between the two worlds.
 Wrapping 𝑪 structures:-
1. Value Delta - Wrap - street (Value class
(), void (*free) ( ), void *pto)

 Wraps the given (data type ptr, registers. The two garbage collection routines and
returns a value pointer to a genuine ruby object.
2. Value data –Make -structure (value class, C-type, voide (*Mask) (), void (*free) ()
(-type*)
-Allocates and sets to zero a structure of the indicated type first & then proceeds as Data -
wrap-street, C-trjpe is the name of data type that quire wrapping, not a variable of that type.

3. Data-Get-strect (value obj. c-type; c-type*)


Returns the original pointer. Data-Gci-struct is a bype-sate wrapper around the macro
Data-PTR (obj) which evaluates the pointer.
Object Creation:-
creating an object of class (D player in our)

Ruby program:

𝑐𝑑 = 𝐶𝐷 player.new

 the implementation of new in class is simple, if allocates memory for new object
then calls the object in initialize method to initialize that memory.
 So, we need to implement an allocation functions and an initialize method.

Mr. AZMEERA RAMESH (ASSIT. PROF), CMRTC


7
Exten Extending Ruby

Ruby Programming for Wrapping of ‘C’ Structure In C Extension.


 To wrap a C structure in a Ruby C extension, you need to define the structure in C,
create functions to manipulate it, and then expose those functions to Ruby through
the C extension. Here's a simple example:
 Let's say we have a C structure representing a point with x and y coordinates:

C Extension (example.c):

#include "ruby.h"

// Define the C structure

typedef struct {

int x;

int y;

} Point;

// Function to create a new Point instance

static VALUE point_initialize(VALUE self, VALUE x, VALUE y) {

Point *point;

Data_Get_Struct(self, Point, point);

point->x = NUM2INT(x);

point->y = NUM2INT(y);

return self;

// Function to get the x coordinate

static VALUE point_get_x(VALUE self) {

Point *point;

Data_Get_Struct(self, Point, point);

Mr. AZMEERA RAMESH (ASSIT. PROF), CMRTC


8
Exten Extending Ruby

return INT2NUM(point->x);

// Function to get the y coordinate

static VALUE point_get_y(VALUE self) {

Point *point;

Data_Get_Struct(self, Point, point);

return INT2NUM(point->y);

// Function to set the x coordinate

static VALUE point_set_x(VALUE self, VALUE new_x) {

Point *point;

Data_Get_Struct(self, Point, point);

point->x = NUM2INT(new_x);

return new_x;

// Function to set the y coordinate

static VALUE point_set_y(VALUE self, VALUE new_y) {

Point *point;

Data_Get_Struct(self, Point, point);

point->y = NUM2INT(new_y);

return new_y;

// Function to allocate memory for a new Point instance

static VALUE point_alloc(VALUE class) {

Mr. AZMEERA RAMESH (ASSIT. PROF), CMRTC


9
Exten Extending Ruby

Point *point = malloc(sizeof(Point));

return Data_Wrap_Struct(class, NULL, free, point);

// Initialization method called when the extension is loaded

void Init_example(void) {

VALUE cExample = rb_define_class("Example", rb_cObject);

rb_define_alloc_func(cExample, point_alloc);

rb_define_method(cExample, "initialize", point_initialize, 2);

rb_define_method(cExample, "x", point_get_x, 0);

rb_define_method(cExample, "y", point_get_y, 0);

rb_define_method(cExample, "x=", point_set_x, 1);

rb_define_method(cExample, "y=", point_set_y, 1);

Compilation:

To compile the C extension, you'll need to create a extconf.rb file:

# extconf.rb

require 'mkmf'

create_makefile('example')

Run the following commands in your terminal:

ruby extconf.rb

make

Using the Extension in Ruby:

Now, you can use the C extension in Ruby:

# main.rb

require_relative 'example'

Mr. AZMEERA RAMESH (ASSIT. PROF), CMRTC


10
Exten Extending Ruby

point = Example.new(10, 20)

puts "Initial Point: (#{point.x}, #{point.y})"

point.x = 30

point.y = 40

puts "Updated Point: (#{point.x}, #{point.y})"

Run the Ruby script:

ruby main.rb

This example demonstrates how to create a Ruby C extension that wraps a C structure
(Point) and provides methods to manipulate its data.

Allocation Functions:

 the allocation function in responsible for creating the memory used by object.
 If the object implementing doesn't use any data other than Ruby instance variables,
Than you don't reed to write an allocation function -Ruby's default allocator roll
work just fine
 But if you class wraps a (structure, you) need to allocate space for that structure in
the allocation function.
 the allocation function gets passed the class of the object being allocated.
 the allocation function crater am empty uninitialized object & we need to fill in
specific values

Cloning object:
 All ruby objects can be copied using one of. two methods dup and clone. Both
produce a need instance of their receiver's class by? Calling the allocation function.
 Then they copy across any instance variables from the original. clone than goes a
bit further and copies the singleton class and flags.
 After copying the objects instance variables. the interpreter involves the new object
is initializing. copy method, passing in a reference to the original Object.
-To test the original object code (original) checks: → than a type of data and

→ Hos a free function with same address as our free function.

Explain About Objects Creation And Cloning Of Objects In Ruby

Ruby, objects are instances of classes, and they are created using the new method of a class.
Additionally, Ruby provides a mechanism for cloning objects, allowing you to create a
duplicate with the same state as the original. Let's explore both aspects:

Mr. AZMEERA RAMESH (ASSIT. PROF), CMRTC


11
Exten Extending Ruby

1. Object Creation:
a. Using the new method:

 Objects in Ruby are created by instantiating a class using the new method.

Example:

go

Copy code

```ruby

class MyClass

def initialize(name)

@name = name

end

end

# Creating an instance of MyClass

my_object = MyClass.new("Example")

 In this example, my_object is an instance of the MyClass class.

b. Object Initialization:

 The initialize method in a class is called when an object is created. It is used for
setting up initial state or performing any necessary setup.

go

```ruby

class Person

def initialize(name, age)

@name = name

Mr. AZMEERA RAMESH (ASSIT. PROF), CMRTC


12
Exten Extending Ruby

@age = age

end

end

person = Person.new("John", 25)

```

 The initialize method here sets the name and age instance variables for the person
object during its creation.

2. Cloning Objects:

a. Using the clone method:

 Ruby provides a clone method that creates a shallow copy of an object. The cloned
object is a duplicate, sharing the same class and initial state, but it has a separate
identity.

go

ruby

go

original_object = MyClass.new("Original")

cloned_object = original_object.clone

```

cloned_object is now a separate instance with the same state as original_object.

b. Using the dup method:

 The dup method is similar to clone but creates a shallow copy without copying the
frozen state of the object.

go

```ruby

makefile

original_array = [1, 2, 3]

cloned_array = original_array.dup

Mr. AZMEERA RAMESH (ASSIT. PROF), CMRTC


13
Exten Extending Ruby

```

cloned_array is a shallow copy of original_array.

3. Deep Copy:

If you need a deep copy, where nested objects are also duplicated, you might need to
implement a custom method or use a library like deep_cloneable or deep_dup.

go

```ruby

javascript

require 'deep_cloneable'

original_hash = { key: [1, 2, 3] }

cloned_hash = original_hash.deep_clone

```

Libraries like deep_cloneable can provide a more comprehensive cloning mechanism for
complex objects.

Remember that cloning in Ruby might not always result in a true deep copy, especially for
complex objects or objects with references to other objects. Depending on your use case,
you may need to implement a custom clone method or use additional libraries for deep
copying

(3) Memory Allocation.

 sometime ls we need to allocate memory in an attention" that won't because for


object storage perhaps you have a (gain) giant bit map for a Boolean titter, an image
or a whole bunch of riffle structure is that Ruby doesn't we directly. titer, an image
is that Ruby doesn’t use directly.
 To work correctly with the garbage collector. We
should use the following morn allocation
these routines do a little bit more wok routines. These routines do a little bit more
work than (then) the standard mallow function
 type * ALLDC-N (C-type, 𝑛)
 Allocates 𝑛 C-type objects where c-type is the literal name of the c-type, not a
variable of that type.
 type * ALLD(c-type)

Mr. AZMEERA RAMESH (ASSIT. PROF), CMRTC


14
Exten Extending Ruby

 Allocates a ectype of c-type (not a variable) (of that (c-type) & 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(R-type,n)

 Allocates memory for 𝑛 Objects of c-type on the stack - this memory will be auto
invokes ALLOCA-N returns.
Memory allocation is a fundamental concept in computer programming, including
scripting languages. It refers to the process of reserving and managing a region of a
computer's memory for a specific purpose, typically to store data during the execution of a
program. Memory allocation is crucial for dynamically managing data structures, objects,
variables, and other runtime entities.

Concept of Memory Allocation


Here's an overview of memory allocation concepts in the context of scripting languages:

1. Static Memory Allocation:


 In some languages, memory is allocated at compile-time, and the size is fixed
throughout the program's execution.
 Static memory allocation is often associated with primitive data types and fixed-
size arrays.
 Examples of statically allocated memory in scripting languages might include
variables declared with a fixed size or global constants.
2. Dynamic Memory Allocation:
 Many scripting languages support dynamic memory allocation, allowing programs
to allocate and release memory during runtime.
 Dynamic memory allocation is essential for managing data structures whose size is
not known at compile-time, such as arrays, linked lists, or objects.
 Scripting languages often provide high-level abstractions for dynamic memory
allocation, making it easier for developers to work with memory without manual
memory management.
3. Garbage Collection:
 In many scripting languages, memory is automatically managed through garbage
collection.
 Garbage collection is a process that automatically identifies and reclaims memory
that is no longer in use by the program.
 It helps prevent memory leaks by freeing up memory occupied by objects that are
no longer accessible.

Mr. AZMEERA RAMESH (ASSIT. PROF), CMRTC


15
Exten Extending Ruby

4. Manual Memory Management:


 Some low-level scripting languages, or those with explicit memory management
features, may require developers to manually allocate and deallocate memory.
 Manual memory management involves using functions like malloc, free, new, and
delete to allocate and release memory.
 This approach provides more control over memory usage but also introduces the
risk of memory leaks or segmentation faults if not managed carefully.
5. Memory Pools and Caches:
 In certain scenarios, scripting languages may use memory pools or caches to
improve memory allocation efficiency.
 Memory pools involve preallocating a large block of memory and then subdividing
it into smaller chunks as needed.
 Caching mechanisms may be used to reuse previously allocated memory blocks,
reducing the overhead of frequent allocations and deallocations.
6. Memory Fragmentation:
 Fragmentation can occur when memory becomes divided into small, non-
contiguous blocks.
 It may lead to inefficient memory usage, making it challenging to allocate large
contiguous blocks, especially in long-running programs.
 Some scripting languages address this issue through memory compaction or other
optimization techniques.
 Memory allocation strategies and mechanisms can vary widely among scripting
languages based on their design goals, paradigms, and levels of abstraction. High-
level scripting languages often abstract away low-level memory details to provide
simplicity and ease of use for developers, while low-level languages may offer
more direct control over memory allocation and deallocation.
(4) Ruby Type system:

 In Ruby we rely lesson the type an object and more on it se capabilities. This known
as Duck typing..
 Hence, Duck Typing means an object type is defined by what it can do not by what
it if duck typing refers to the tendency of Ruby to be less concerned with the class
of an object more concerned with what methods can be called on if twat operations
cam be performed on it.
 In Ruby, we would use respond to 2 or might simply pass an object to a method
and know that on exception will be raised if it is used in appropriately.

 It an object walks like advert and talks like a deck, then the Ruby interpreter is
happy to treats if as if if were a duck.
 Eg :- #check, whether the object defines the...

to str method

→ 'A string', respond - to ?(: to → str )

Mr. AZMEERA RAMESH (ASSIT. PROF), CMRTC


16
Exten Extending Ruby

⇒ true

⇒ Exception.new.respond- to? ('to-str)

⇒ false

⇒ 4. respond -to: (: to-str)

⇒ false

The above example is 𝑥 a type of duck typing If an object quack like a duck (or) acts just
go ahead it treat it as a duck objects according to methods they define rather than the classes
from which they inherit or the modules They include.

The Ruby Type System

Ruby is a dynamically-typed language with a strong and flexible type system. This means
that the type of a variable or object is determined and checked at runtime, and the language
provides a lot of flexibility in how variables and objects are used. Here are key aspects of
the Ruby type system:

1. Dynamic Typing:

Ruby is dynamically typed, meaning you don't have to declare the type of a variable when
you create it. The type is determined and can change during runtime.

go

```ruby

makefile

x = 10 # x is Fixnum

x = "hello" # x is now a String

```

2. Strong Typing:

While Ruby is dynamically typed, it is also strongly typed. This means that the interpreter
enforces strict type rules, and implicit type conversions are limited.

go

```ruby

graphql

Mr. AZMEERA RAMESH (ASSIT. PROF), CMRTC


17
Exten Extending Ruby

"10" + 5 # TypeError: String can't be coerced into Integer

```

In the example above, Ruby does not automatically convert the string "10" to an integer
for the addition operation.

3. Object-Oriented:

Everything in Ruby is an object, including primitive data types like integers and booleans.
Objects encapsulate both data and behavior.

go

```ruby

perl

"hello".length # Invoking a method on a String object

```

4. Type Coercion:

Ruby supports some level of automatic type coercion for common operations. For example,
it can automatically convert a Fixnum to a Float in a mathematical operation.

go

```ruby

makefile

result = 5 + 2.0 # 5 is coerced to 5.0 for the addition

```

5. NilClass:

Ruby has a special nil value, which represents the absence of a value. It is an instance of
the NilClass.

go

```ruby

go

x = nil

Mr. AZMEERA RAMESH (ASSIT. PROF), CMRTC


18
Exten Extending Ruby

```

6. Arrays and Hashes:

Arrays and hashes in Ruby can hold elements of different types.

go

```ruby

ruby

mixed_array = [1, "two", 3.0, :four]

```

7. Duck Typing:

Ruby follows the principle of "duck typing," where the type or the class of an object is less
important than the methods it responds to.

If an object quacks like a duck (responds to the expected methods), then it's treated as a
duck.

go

```ruby

ruby

def print_length(obj)

puts obj.length

end

print_length("hello") # Prints the length of the string

print_length([1, 2, 3]) # Prints the length of the array

```

8. Type Checking:

Ruby provides methods like is_a? and kind_of? for type checking.

go

```ruby

Mr. AZMEERA RAMESH (ASSIT. PROF), CMRTC


19
Exten Extending Ruby

x = 42

puts x.is_a?(Integer) # true

puts x.is_a?(String) # false

```

9. Symbols:

Ruby has a distinct Symbol class, which is often used as identifiers.

go

```ruby

:symbol_name

```

The Ruby type system is designed to provide a balance between flexibility and reliability,
allowing developers to write expressive and concise code while still benefiting from the
advantages of a strongly typed language.

(5) Embedding Ruby to other languages

 When you first look at some Ruby code, if will likely remind you of other
programming languages we have used.

 this is because of the syntax is familiar to users of perl.python, and java etc,

c and 𝑐 + 𝑡;

"Rub and 𝑐 have healthy" symbiotic relationship.

→ Similarities with : as with 𝑐, in Ruby public private and protected dosimilar jobs.

 Exceptions work in a Similar manner, through the keyword names have been
changed to protect the innocent.
Java:

 java is nature. Its tested And it is fast.


 Going from java to ruby, except your code size to shrink down considerably. we
can also expect if to take less time to knock together quick prototypes
 Similarities: As with java. in Ruby Memory is managed for you via a garbage
Perl:

Mr. AZMEERA RAMESH (ASSIT. PROF), CMRTC


20
Exten Extending Ruby

 pert docks are awesome -for those perter who 10ng for ekgant object oriented
feature ss builtin from the beginning. Ruby com help.
 Similarities: As with Perl, in Ruby
 parentheses are (bass) offer optional.
 strings work basically the same.
PHP:

 PHP is in widespread use for web applications. But if you want to use Ruby on rails
or just Want a language that's more fathered for general use. Ruby is worth a look.
 Similarities: As in Php. in Ruby
 Ruby is dynamically typed like in PHP. So you don’t need to worry about having
to declare Vanciblets.

 Some variables start with $, like in pip (but not all).

 This kind of hands off manipulation of Ruby programs from within c cock is easy
but it (interpreter if self. The call to ruby -init) has too major drawbacks. first, it is
indirect-we hare to keep storing things in global t extracting the values from these
global or et to use them.

 second we (will) are not doing any real error checking. Which will definitely bite
us later. Co, the send way to interact with Ruby code is to use the (API).

→ second. we will interact by evaluating ApI

 this gives us much finer grained control also lets us handle errors.
 we can do this by initializing the interpreter as normal, then, rather than evaluating
string instead invoke specific methods in your Ruby code.
 when these methods. returns, your (code get) control back.
Embedded Ruby API

Void ruby- int( ):-

setup 𝑓 initializes the interpreter. This function be called before any other ruby-related
function.

Python:

 python is another very mice general purpose programming languages.


 Similarities: As with python. in Ruby
 -string literals can span multiple lines like python triple quoted string ls.

 Objects are strongly and dynamically typed.

Mr. AZMEERA RAMESH (ASSIT. PROF), CMRTC


21
Exten Extending Ruby

 there is good support for functional programming with first -class functions.
Anonymous functions and clotures.
(6) Embedding a Ruby Interpreter:

 In addition to extending Ruby by adding 𝑐 code, you cars also turn the problem
around 𝑅 embed Ruby itself within your application.
 We can interact Ruby by (API) or by evaluating strings
→ First we will interact by evaluating strings of Ruby code:

 To initialize the Ruby interpreter we need to call ruby-sysinit () to picker


command-line arguments used by Ruby. Ruby-init-stack to setup the ruby stack,
and ruby-init to initialize the interpreter if self. The call to ruby-init-loadpath adds
any directioriers to be seouched for libraries s
Void ruby-init- loadpath():-

 Initializes the $ : variable; necessary if your code loads any library modulus.
Void ruby - options (int, arg c, Shan ** argv):-

 Gives the ruby interpreter the command-line Options.


Void ruby-script (Char* name):

 self s the name of the ruby ascropto to name.


Void rb-load file (Char* file)

 Loads the given file into the interpreter.


void ruby-run( ):

 Rungs the interpreter


void ruby = finalize ():

 shuts down the interpreter.


How Can You Embedding Ruby Interpreters?
 Embedding a Ruby interpreter into another application involves integrating Ruby
code into a program written in another language, such as C or C++. This allows the
application to execute Ruby code and interact with Ruby objects.
 Ruby provides a C API that facilitates embedding the interpreter, and here are
general steps for embedding a Ruby interpreter:
 Include Ruby Headers:
 Ensure that you have the Ruby development headers installed on your system.
 Include the necessary Ruby headers in your C or C++ source file:
#include <ruby.h>

Mr. AZMEERA RAMESH (ASSIT. PROF), CMRTC


22
Exten Extending Ruby

 Initialize the Ruby Interpreter:


 Before using any Ruby functionality, initialize the Ruby interpreter:
 ruby_init();
 ruby_init_loadpath();
 ruby_init_loadpath() initializes the load path, which is required for loading Ruby
scripts.
Run Ruby Code:
You can evaluate Ruby code using the rb_eval_string function: c
VALUE result = rb_eval_string("puts 'Hello from Ruby!'");
This executes the provided Ruby code and returns the result.
Error Handling:
Check for errors after executing Ruby code:
if (rb_errinfo()) {
// Handle Ruby error
ruby_errinfo_print();
ruby_errinfo_clear();
}
This snippet checks for an error, prints it, and then clears the error information.
Interact with Ruby Objects:
You can call Ruby methods and access Ruby objects from C:
VALUE my_variable = rb_str_new_cstr("Hello from C!");
rb_funcall(result, rb_intern("concat"), 1, my_variable);
This example appends the C string to the result obtained from the Ruby code.
Finalize the Interpreter:
Before exiting your program, ensure that you finalize the Ruby interpreter: c
ruby_cleanup(0);
This cleans up resources used by the Ruby interpreter.
Here's a simple example:
#include <ruby.h>
int main() {
ruby_init();
ruby_init_loadpath();
VALUE result = rb_eval_string("puts 'Hello from Ruby!'");
if (rb_errinfo()) {

Mr. AZMEERA RAMESH (ASSIT. PROF), CMRTC


23
Exten Extending Ruby

ruby_errinfo_print();
ruby_errinfo_clear();
}
VALUE my_variable = rb_str_new_cstr("Hello from C!");
rb_funcall(result, rb_intern("concat"), 1, my_variable);
ruby_cleanup(0);
return 0;
}
 Remember that this is a basic example, and depending on your application, you
may need to handle more complex scenarios, manage memory properly, and handle
Ruby exceptions and errors appropriately

Mr. AZMEERA RAMESH (ASSIT. PROF), CMRTC

You might also like