extendig ruby: defining classes and creating objects from c

A

An Onymous

I can't manage to define a new class (actually an exception) and then
instantiating it from C.
I define the class with:
xr_cException = rb_define_class_under(xr_module, "Exception",
rb_eRuntimeError);
rb_define_method(xr_cException, "initialize",
xr_cException_initialize, 4);
...
static VALUE xr_cException_initialize(VALUE self, VALUE status, VALUE
lasterror, VALUE function, VALUE msg)
{
rb_iv_set(self, "@status", status);
rb_iv_set(self, "@lasterror", lasterror);
rb_iv_set(self, "@function", function);
rb_iv_set(self, "@msg", msg);
return self;

At this point I can write a ruby test program like
a=MYMOD::Exception.new(1,2,3,4)
raise a, "Hello!"
and it works all right and I get output:
Test.rb:5: Hello! (MYMOD::Exception)

However if I try to do the same thing from C with:
VALUE oException, argv[4]={INT2FIX(1), INT2FIX(2), INT2FIX(3),
INT2FIX(4)};
oException = rb_class_new_instance(4, argv, xr_cException);
rb_raise(oException, "Hello!");
I put this piece of code inside a method named raiseit and call test
from a test ruby program. I get error:
Test.rb:9:in `raiseit': undefined method `new' for #<MYMOD::Exception:
MYMOD::Exception> (NoMethodError)

It seems that when I try to create an object of type MYMOD::Exception,
somehow ruby doesn't find the new method. I've tried to define also a
new method for this class, but I get the same error.
By the way, the function rb_call_new_instance seems to be quite
undocumented...

What is the correct way to create a new object of a given class from C?

Thanks
libit
 
N

Nobuyoshi Nakada

Hi,

At Sat, 20 Oct 2007 00:56:16 +0900,
An Onymous wrote in [ruby-talk:274836]:
rb_raise(oException, "Hello!");

The first argument of rb_raise() is a class. Try:

rb_exc_raise(oException);
 
A

An Onymous

Oh, so ruby was looking for a "new" method not on the class but on the
instance.
This explains the problem, however how do I raise an exception from an
object?
rb_exc_raise(oException);

rb_exc_raise is not defined in ruby.h. At least not in the latest
version 1.8.6
What is it? I see it defined in intern.h and called from everywhere but
I can't find where it is defined.

libit
 
N

Nobuyoshi Nakada

Hi,

At Sat, 20 Oct 2007 04:33:33 +0900,
An Onymous wrote in [ruby-talk:274879]:
rb_exc_raise is not defined in ruby.h. At least not in the latest
version 1.8.6

It's declared in intern.h which is included by ruby.h.
What is it? I see it defined in intern.h and called from everywhere but
I can't find where it is defined.

In eval.c.
 
A

An Onymous

Thank you. Now it works.
I ended up writing an updated version of rb_raise which behaves more
like the ruby "raise" global function. That is:
myrb_raise(Qnil,NULL) behaves like "raise"
myrb_raise(Qnil,fmt,...) behaves like "raise <string>" raising a
RuntimeError with the given message
myrb_raise(exc,NULL) behaves like "raise <exc>" where exc can be either
a class OR AN EXCEPTION OBJECT (if exc is an exception object, its
message is preserved)
and
myrb_raise(exc,fmt,...) behaves like "raise <exc>,<string>" that is like
the previous one but also setting the exception message.

Here it is:
VALUE myrb_raise(VALUE exc, const char *fmt, ...)
{
if(!NIL_P(exc)) {
ID exception = rb_intern("exception");
if(!rb_respond_to(exc, exception)) rb_raise(rb_eTypeError,
"exception class/object expected");
}
if(fmt) {
va_list args;
char buf[BUFSIZ];
VALUE msg;
va_init_list(args,fmt);
vsnprintf(buf, BUFSIZ, fmt, args);
va_end(args);
msg=rb_str_new2(buf);
if(NIL_P(exc)) exc = rb_class_new_instance(1, &msg,
rb_eRuntimeError);
else exc = rb_funcall(exc, exception, 1, msg);
}
rb_exc_raise(exc);
}
 
A

An Onymous

Actually the first few lines should read:
VALUE myrb_raise(VALUE exc, const char *fmt, ...)
{
ID exception;
if(!NIL_P(exc)) {
exception = rb_intern("exception");
...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,226
Members
46,815
Latest member
treekmostly22

Latest Threads

Top