[go: up one dir, main page]

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

SL Unit-Ii

Scripting language unit2
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)
33 views23 pages

SL Unit-Ii

Scripting language unit2
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

UNIT – II

2.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.
Extending Ruby with C is pretty easy. For instance, suppose we are building a custom Internet-ready
jukebox for the Sunset Diner and Grill. It will play MP3 audio files from a hard disk or audio CDs
from a CD jukebox. We want to be able to control the jukebox hardware from a Ruby program. The
hardware vendor gave us a C header file and a binary library to use; our job is to construct a Ruby
object that makes the appropriate C function calls.
But before we can get Ruby and C to work together, we need to see what the Ruby world looks like
from the C side.[Much of the information in this chapter is taken from the README.EXT file that is
included in the distribution. If you are planning on writing a Ruby extension, you may want to refer to
that file for more details as well as the latest changes.

Extending Ruby usually refers to adding functionality to the Ruby language itself, typically through
the use of Ruby's C API. This allows developers to write Ruby extensions in C that can then be used
seamlessly within Ruby programs.

Ruby's C API provides a way to interact with Ruby's internal data structures and functions, allowing
developers to create custom classes, modules, and methods that can be called from Ruby code.
Extending Ruby can be useful for integrating with existing C libraries, optimizing performance-critical
code, or adding functionality that isn't available in standard Ruby libraries.

Extending Ruby in scripting languages typically involves leveraging Ruby's ability to interact with
code written in other languages like C, C++, or even languages like Python or JavaScript. This allows
developers to incorporate functionality from these languages into their Ruby scripts.

For example, you can use Ruby's Fiddle library to dynamically load and call functions from shared
libraries written in C. This is particularly useful for interfacing with system-level functionality or
performance-critical operations. Similarly, you can use libraries like Rjb (Ruby Java Bridge) or PyCall
(Python in Ruby) to interact with Java or Python code respectively from within Ruby scripts. By
extending Ruby with scripting languages, developers can take advantage of the strengths of each
language and incorporate diverse functionality into their Ruby applications.

The extension we write will have the same functionality as the following Ruby class:

class MyTest
def initialize

@arr = Array.new

end

def add(obj)

@arr.push(obj)

end

end

That is, we’ll be writing an extension in C that is plug-compatible with that Ruby class. The

equivalent code in C should look somewhat familiar:

#include "ruby.h"

static ID id_push;

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 obj)

VALUE arr;

arr = rb_iv_get(self, "@arr");

rb_funcall(arr, id_push, 1, obj);

return arr;

}
VALUE cTest;

void Init_my_test() {

cTest = rb_define_class("MyTest", rb_cObject);

rb_define_method(cTest, "initialize", t_init, 0);

rb_define_method(cTest, "add", t_add, 1);

id_push = rb_intern("push");

Let’s go through this example in detail, because it illustrates many of the important concepts in this
chapter. First, we need to include the header file ruby.h to obtain the necessary Ruby definitions.

Now look at the last function, Init_my_test. Every extension defines a C global function named
Init_name. This function will be called when the interpreter first loads the extension name (or on
startup for statically linked extensions). It is used to initialize the extension and to insinuate it into the
Ruby environment. (Exactly how Ruby knows that an extension is called name we’ll cover later.) In
this case, we define a new class named MyTest, which is a subclass of Object (represented by the
external symbol rb_cObject; see ruby.h for others).

Next we define add and initialize as two instance methods for class MyTest. The two calls to
rb_define_method establish a binding between the Ruby method name and the C function that will
implement it. If Ruby code calls the add method on one of our objects, the interpreter will in turn call
the C function t_add with one argument.

Similarly, when new is called for this class, Ruby will construct a basic object and then call initialize,
which we have defined here to call the C function t_init with no (Ruby) arguments.

Now go back and look at the definition of t_init. Even though we said it took no arguments, it has a
parameter here! In addition to any Ruby arguments, every method is passed an initial VALUE
argument that contains the receiver for this method (the equivalent of self in Ruby code).

The first thing we’ll do in t_init is create a Ruby array and set the instance variable @arr to point to
it. Just as you would expect if you were writing Ruby source, referencing an instance variable that
doesn’t exist creates it. We then return a pointer to ourselves.

WARNING: Every C function that is callable from Ruby must return a VALUE, even if it’s just Qnil.
Otherwise, a core dump (or GPF) will be the likely result. Finally, the function t_add gets the instance
variable @arr from the current object and calls Array#push to push the passed value onto that array.
When accessing instance variables in this way, the @ prefix is mandatory—otherwise, the variable is
created but cannot be referenced from Ruby.

2.1.1 Ruby Objects in C


The first thing we need to look at is how to represent and access Ruby datatypes from within C.
Everything in Ruby is an object, and all variables are references to objects. In C, this means that the
type of all Ruby variables is VALUE, which is either a pointer to a Ruby object or an immediate value
(such as Fixnum).
This is how Ruby implements object-oriented code in C: a Ruby object is an allocated structure in
memory that contains a table of instance variables and information about the class. The class itself is
another object (an allocated structure in memory) that contains a table of the methods defined for that
class.

 Working with Immediate Objects

As we said earlier, immediate values are not pointers: Fixnum, Symbol, true, false, and nil are stored
directly in VALUE.

Fixnum values are stored as 31-bit numbers1 that are formed by shifting the original number left 1 bit
and then setting the LSB, or least significant bit (bit 0), to 1. When VALUE is used as a pointer to a
specific Ruby structure, it is guaranteed always to have an LSB of zero; the other immediate values
also have LSBs of zero. Thus, a simple bit test can tell you whether you have a Fixnum. This test is
wrapped in a macro, FIXNUM_P. Similar tests let you 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

In Ruby, objects are instances of classes, and they are created and manipulated within the Ruby
interpreter. However, Ruby provides a C API that allows developers to interact with Ruby objects and
the interpreter from C code. To work with Ruby objects in C, you typically include the <ruby.h> header
file, which provides access to the Ruby C API. This API allows you to create Ruby objects, call Ruby
methods, access object attributes, and more from within your C code.
Here's a simple example of how you might create a Ruby object in C:

In this example:

 ruby_init() initializes the Ruby interpreter.


 rb_str_new_cstr() creates a new Ruby string object from a C string.
 RSTRING_PTR() extracts the pointer to the C string data from the Ruby string object.

This is just a basic example to demonstrate the concept. In practice, you can do much more with the
Ruby C API, such as creating custom Ruby classes and objects, calling Ruby methods with arguments,
defining Ruby modules and functions, and more.

Working with Ruby objects in C involves understanding the Ruby C API and how Ruby represents
objects internally. Let's delve into a bit more detail about how you can work with Ruby objects in C.

1. Include the Ruby Header File: To work with Ruby objects in C, you need to include the
<ruby.h> header file, which provides access to the Ruby C API.
2. Initialize and Finalize the Ruby Interpreter: Before interacting with Ruby objects, you need
to initialize the Ruby interpreter using ruby_init() and finalize it when you're done using
ruby_cleanup().

3. Create Ruby Objects: Ruby objects in C are represented by the VALUE type, which is a
typedef for a pointer to a Ruby object. You can create Ruby objects using various functions
provided by the Ruby C API.

For example, to create a new string object:

4. Accessing Ruby Object Attributes and Methods: Once you have a Ruby object, you can
access its attributes and methods using functions provided by the Ruby C API. For example, to
get the length of a string object:

To call a method on an object:


5. Converting Between C and Ruby Types: Ruby objects can be converted to C types and vice
versa using functions provided by the Ruby C API. For example, to convert a Ruby string to a
C string:

6. Memory Management: When working with Ruby objects in C, you need to be mindful of
memory management. Ruby uses a garbage collector to manage memory, so you typically don't
need to free memory explicitly. However, you should be careful when creating new objects in
C to avoid memory leaks.
7. Error Handling: Error handling in C is crucial when working with Ruby objects. Many
functions in the Ruby C API return special values to indicate errors, so you should always
check return values and handle errors appropriately.
8. Advanced Usage: The Ruby C API provides many more functions and features for working
with Ruby objects, including creating custom Ruby classes and modules, defining methods,
manipulating arrays and hashes, and more. Advanced usage of the Ruby C API requires a deep
understanding of both C and Ruby.

Working with Ruby objects in C can be complex, but it allows you to extend Ruby with high-
performance C code and integrate with existing C libraries. If you're interested in learning more, the
official Ruby documentation and source code are valuable resources.

2.1.2 The Jukebox Extension

Introducing the Ruby Jukebox Extension

The Ruby Jukebox Extension! Designed to bring music playback and management seamlessly into
your Ruby projects, this extension empowers developers to create immersive audio experiences with
ease.

 Key Features:

1. Music Playback: Enjoy smooth playback of audio files directly within your Ruby applications.
Whether it's your favorite tunes or custom soundtracks, the Jukebox Extension handles it all.
2. Playlist Management: Organize your music collection effortlessly with powerful playlist
management features. Create, edit, and shuffle playlists on the fly, providing users with a
personalized listening experience.
3. User-Friendly Interface: With an intuitive user interface, users can navigate through their
music library, control playback, and adjust volume with ease. The Jukebox Extension provides
a seamless audio experience for users of all levels.
4. Customization Options: Tailor the Jukebox Extension to suit your project's unique
requirements. Customize playback controls, UI elements, and behavior to seamlessly integrate
music functionality into your Ruby applications.
5. Cross-Platform Compatibility: Whether you're developing for web, desktop, or mobile
platforms, the Jukebox Extension ensures consistent performance and compatibility across
different environments.

 Getting Started:

Getting started with the Ruby Jukebox Extension is a breeze! Simply install the gem via RubyGems
or include it as a dependency in your Gemfile. With comprehensive documentation and examples
provided, you'll be up and running in no time, ready to elevate your Ruby projects with the magic of
music.

 Join the Community:

Become part of our vibrant community of developers, sharing ideas, tips, and insights on how to make
the most of the Ruby Jukebox Extension. Connect with fellow enthusiasts, contribute to the project,
and explore new possibilities for integrating music into your Ruby applications.

In January 2022, there isn't a widely known or established Ruby gem or library specifically named
"Jukebox extension." However, it's possible that such a project could have emerged or gained
popularity since then.

If you're referring to a specific Ruby extension or gem related to jukebox functionality, it might be a
custom project or a relatively new development in the Ruby community. Without more specific
information, it's challenging to provide detailed insights into its features or usage.

Here's a general overview of what a "Jukebox extension" in Ruby might entail:

1. Music Playback: The extension could include features for playing audio files, managing
playlists, and controlling playback within Ruby applications.
2. Integration with Music Services: It might offer integration with online music services or
APIs, allowing developers to build applications that stream or access music content.
3. User Interface: A jukebox extension could include components for creating a user interface
(UI) for interacting with music playback features, such as buttons for controlling playback,
displaying song information, and managing playlists.
4. Customization and Configuration: Developers might be able to customize the behavior and
appearance of the jukebox extension through configuration options or by extending its
functionality with custom code.
5. Documentation and Examples: Good documentation and examples are essential for any Ruby
gem or library. They help developers understand how to use the extension effectively and
provide guidance on common use cases and best practices.

Interfacing C code with Ruby and sharing data and behavior between the two worlds.

 Wrapping C Structures

We have the vendor’s library that controls the audio CD jukebox units, and we’re ready to wire it
into Ruby. The vendor’s header file looks like this:

typedef struct _cdjb {

int statusf;

int request;

void *data;

char pending;

int unit_id;

void *stats;

} CDJukebox;

// Allocate a new CDJukebox structure

CDJukebox *new_jukebox(void);

// Assign the Jukebox to a player

void assign_jukebox(CDJukebox *jb, int unit_id);


// Deallocate when done (and take offline)

void free_jukebox(CDJukebox *jb);

// Seek to a disc, track and notify progress

void jukebox_seek(CDJukebox *jb,

Wrapping Objects Around C Datatypes

int disc,

int track,

void (*done)(CDJukebox *jb, int percent));

// ... others...

// Report a statistic

double get_avg_seek_time(CDJukebox *jb);

This vendor has its act together; although they might not admit it, the code is written with an object-
oriented flavor. We don’t know what all those fields mean within the CDJukeBox structure, but that’s
OK—we can treat it as an opaque pile of bits. The vendor’s code knows what to do with it; we just
have to carry it around.
Any time you have a C-only structure that you would like to handle as a Ruby object, you should wrap
it in a special, internal Ruby class called DATA (type T_DATA). Two macros do this wrapping, and
one macro retrieves your structure back out again.

Creating a Jukebox extension in C for Ruby involves defining functions that interact with Ruby objects
related to audio and managing a playlist. Here's a simplified example:

1. Create a C file (e.g., jukebox.c) and include the necessary headers:

2. Define C functions for your Jukebox operations:


3. Register the functions in the initialization function:

4. Compile the extension:

5. Use the Jukebox extension in your Ruby code:

This is a basic structure, and you would need to implement the actual functionality for handling audio
playback, playlist management, etc., in the C functions. Additionally, handling errors, memory
management, and more advanced features would be necessary for a robust extension.

2.1.3 Memory Allocation


In C extensions for Ruby, memory allocation and management are crucial to avoid memory leaks and
ensure proper functioning. Here's a brief overview of memory allocation in a Ruby C extension:

1. Allocate Memory:

 Use malloc or related functions to allocate memory for your data structures.
2. Free Memory:

 Always free allocated memory when it's no longer needed to prevent memory leaks.

3. Ruby Memory Management Functions:

 When dealing with Ruby objects, use Ruby memory management functions to allocate and
deallocate memory.

4. Error Handling:

 Check for memory allocation failures and handle them appropriately.


5. Use Ruby Data Structure Functions:

 When dealing with Ruby data structures (arrays, hashes, etc.), use Ruby API functions to
manipulate them safely.

Remember to manage memory carefully, handle errors, and free resources appropriately to ensure the
stability and reliability of your Ruby C extension.

You may sometimes need to allocate memory in an extension that won’t be used for object storage—
perhaps you have a giant bitmap for a Bloom filter, an image, or a whole bunch of little structures that
Ruby doesn’t use directly.

To work correctly with the garbage collector, you should use the following memory allocation routines.
These routines do a little bit more work than the standard malloc function. 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.
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.

2.1.4 Ruby Type System


Ruby has a dynamic and flexible type system, often referred to as "duck typing." Here are some key
aspects of Ruby's type system:

1. Dynamic Typing:

 In Ruby, you don't declare the type of a variable explicitly. The type of a variable is
determined at runtime based on the value it holds.

2. Object-Oriented:

 Everything in Ruby is an object, including primitive data types like integers and
booleans. Objects in Ruby have methods associated with them.

3. Duck Typing:

 Ruby focuses on the behavior of objects rather than their specific types. If an object
quacks like a duck (responds to the necessary methods), then it's treated as a duck,
regardless of its actual class.

4. Strong Typing:

 While Ruby is dynamically typed, it is also strongly typed. This means that the
interpreter enforces type safety during runtime. Operations between incompatible types
typically result in errors.
5. Open Classes:

 Ruby allows you to modify or reopen existing classes and add new methods to them.
This feature is known as "monkey patching." It provides a high degree of flexibility but
should be used with caution to avoid unintended consequences.

6. Type Conversion:

 Ruby provides methods for explicit type conversion (casting) between different types.
For example, to_i converts an object to an integer, and to_s converts it to a string.

7. Nil:

 Ruby has a special object called nil, which represents the absence of a value or undefined state.
Methods can return nil if there's no meaningful result.

These aspects helps you write more flexible and expressive code in Ruby, taking advantage of the
language's dynamic and object-oriented nature.

2.1.5 Embedding Ruby to Other Languages


Having written the source code for an extension, we now need to compile it so Ruby can use it.

We can either do this as a shared object, which is dynamically loaded at runtime, or statically link the
extension into the main Ruby interpreter itself. The basic procedure is the same:

1. Create the C source code file(s) in a given directory.


2. Optionally create any supporting Ruby files in a lib subdirectory.

3. Create extconf.rb.

4. Run extconf.rb to create a Makefile for the C files in this directory.

5. Run make.

6. Run make install.

 Creating a Makefile with extconf.rb

The overall workflow when building an extension is shown in Figure below, on the next page. The key
to the whole process is the extconf.rb program that you, as a developer, create. extconf.rb is simple
program that determines what features are available on the user’s system and where those features may
be located.

Building an Extension

Executing extconf.rb builds a customized Makefile, tailored for both your application and the system
on which it’s being compiled. When you run the make command against this Makefile, your extension
is built and (optionally) installed. If you have multiple versions of Ruby installed on your system, the
one used when you run extconf.rb is the one your extension is built and installed against.

The simplest extconf.rb may be just two lines long, and for many extensions this is sufficient:

require 'mkmf'

create_makefile("Test")
The first line brings in the mkmf library module. This contains all the commands we’ll be using. The
second line creates a Makefile for an extension called “Test.” (Note that “Test” is the name of the
extension; the file will always be called Makefile.)

Test will be built from all the C source files in the current directory. When your code is loaded,

Ruby will call its Init_Test method.

Let’s say that we run this extconf.rb program in a directory containing a single source file, main.c. The
result is a Makefile that will build our extension. On a Linux box, this executes the following
commands (your commands will likely be different):

gcc -fPIC -I/usr/local/lib/ruby/1.9/i686-linux -g -O2 \

-c main.c -o main.o

gcc -shared -o Test.so main.o -lc

The result of this compilation is Test.so, which may be dynamically linked into Ruby at runtime with
require. Under Mac OS X, the commands are different, but the result is the same; a shared object (a
bundle on the Mac) is created:

Although this basic extconf.rb program works for many simple extensions, you may have to do some
more work if your extension needs header files or libraries that aren’t included in the default
compilation environment or if you conditionally compile code based on the presence of libraries or
functions.

A common requirement is to specify nonstandard directories where include files and libraries may be
found. This is a two-step process. First, your extconf.rb should contain one or more dir_config
commands. This specifies a tag for a set of directories. Then, when you run the extconf.rb program,
you tell mkmf where the corresponding physical directories are on the current system.

If extconf.rb contains the line dir_config(name), then you give the location of the corresponding
directories with the command-line options:

--with-name-include=directory

Adds directory/include to the compile command.

--with-name-lib=directory

Adds directory/lib to the link command.

If (as is common) your include and library directories are subdirectories called include and lib
of the same directory, you can take a shortcut:

--with-name-dir=directory

Adds directory/lib and directory/include to the link command and compile command, respectively. As
well as specifying all these --with options when you run extconf.rb, you can also use the –with options
that were specified when Ruby was built for your machine. This means you can discover and use the
locations of libraries that are used by Ruby itself. It also means that you can specify the locations of
all libraries just once and then rebuild extensions as many times as you like.

To make all this concrete, let’s say you need to use the vendor’s CDJukebox libraries and include files
for the CD player we’re developing. Your extconf.rb may contain this:

require 'mkmf'

dir_config('cdjukebox')

# .. more stuff

create_makefile("CDPlayer")

You’d then run extconf.rb with something like this:

$ ruby extconf.rb --with-cdjukebox-dir=/usr/local/cdjb

The generated Makefile would assume that the directory /usr/local/cdjb/lib contained the libraries and
the directory /usr/local/cdjb/include the include files.

The dir_config command adds to the list of places to search for libraries and include files. It does not,
however, link the libraries into your application. To do that, you’ll need to use one or more have_library
or find_library commands.

have_library looks for a given entry point in a named library. If it finds the entry point, it adds the
library to the list of libraries to be used when linking your extension. find_library is similar but allows
you to specify a list of directories to search for the library.

Here are the contents of the extconf.rb that we use to link our CD player:

require 'mkmf'

dir_config("cdjukebox")

have_library("cdjukebox", "new_jukebox")

create_makefile("CDPlayer")
A particular library may be in different places depending on the host system. The X Window system,
for example, is notorious for living in different directories on different systems. The find_library
command will search a list of supplied directories to find the right one (this is different from
have_library, which uses only configuration information for the search).

For example, to create a Makefile that uses X Windows and a JPEG library, you might craft an
extconf.rb containing the following:

require 'mkmf'

if have_library("jpeg","jpeg_mem_init") and

find_library("X11", "XOpenDisplay",

"/usr/X11/lib", # list of directories

"/usr/X11R6/lib", # to check

"/usr/openwin/lib") # for library

then

create_makefile("XThing")

else

puts "No X/JPEG support available"

end

We’ve added some functionality to this program. All the mkmf commands return false if they fail. This
means we can write an extconf.rb that generates a Makefile only if everything it needs is present. The
Ruby distribution does this so that it will try to compile only those extensions that are supported on
your system.

You also may want your extension code to be able to configure the features it uses depending on the
target environment. For example, our CD jukebox may be able to use a high-performance MP3 decoder
if the end user has one installed.

We can check by looking for its header file:

require 'mkmf'

dir_config('cdjukebox')
have_library('cdjb', 'CDPlayerNew')

have_header('hp_mp3.h')

create_makefile("CDJukeBox")

We can also check to see whether the target environment has a particular function in any of the libraries
we’ll be using. For example, the setpriority call would be useful but isn’t always available.

We can check for it with this:

require 'mkmf'

dir_config('cdjukebox')

have_func('setpriority')

create_makefile("CDJukeBox")

Both have_header and have_func define preprocessor constants if they find their targets. The names
are formed by converting the target name to uppercase and prepending HAVE_.

Your C code can take advantage of this using constructs such as the following:

#if defined(HAVE_HP_MP3_H)

# include <hp_mp3.h>

#endif

#if defined(HAVE_SETPRIORITY)

err = setpriority(PRIOR_PROCESS, 0, -10)

#endif

If you have special requirements that can’t be met with all these mkmf commands, your program can
directly add to the global variables $CFLAGS and $LDFLAGS, which are passed to the compiler and
linker, respectively.
Sometimes you’ll create an extconf.rb and it just doesn’t seem to work. You give it the name of a
library, and it swears that no such library has ever existed on the entire planet. You tweak and tweak,
but mkmf still can’t find the library you need. It would be nice if you could find out exactly what it’s
doing behind the scenes. Well, you can. Each time you run your extconf.rb script, mkmf generates a
log file containing details of what it did. If you look in mkmf.log, you’ll be able to see what steps the
program used to try to find the libraries you requested. Sometimes trying these steps manually will
help you track down the problem.
2.1.6 Embedding a Ruby Interpreter
In addition to extending Ruby by adding C code, you can also turn the problem around and embed
Ruby itself within your application. Here's an example.
#include "ruby.h"

main() {
/* ... our own application stuff ... */
ruby_init();
ruby_script("embedded");
rb_load_file("start.rb");
while (1) {
if (need_to_do_ruby) {
ruby_run();
}
/* ... run our app stuff */
}
}

To initialize the Ruby interpreter, you need to call ruby_init(). But on some platforms, you may need
to take special steps before that:

#if defined(NT)
NtInitialize(&argc, &argv);
#endif
#if defined(__MACOS__) && defined(__MWERKS__)
argc = ccommand(&argv);
#endif

See main.c in the Ruby distribution for any other special defines or setup needed for your platform.

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

You need to take some special care with exception handling; any Ruby calls you make at this top level
should be protected to catch exceptions and handle them cleanly.

You might also like