Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > extendig ruby: defining classes and creating objects from c

Reply
Thread Tools

extendig ruby: defining classes and creating objects from c

 
 
An Onymous
Guest
Posts: n/a
 
      10-19-2007
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
--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
 
 
 
Nobuyoshi Nakada
Guest
Posts: n/a
 
      10-19-2007
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);

--
Nobu Nakada

 
Reply With Quote
 
 
 
 
An Onymous
Guest
Posts: n/a
 
      10-19-2007
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
--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
Nobuyoshi Nakada
Guest
Posts: n/a
 
      10-19-2007
Hi,

At Sat, 20 Oct 2007 04:33:33 +0900,
An Onymous wrote in [ruby-talk:274879]:
> > rb_exc_raise(oException);

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

--
Nobu Nakada

 
Reply With Quote
 
An Onymous
Guest
Posts: n/a
 
      10-20-2007
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);
}



--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
An Onymous
Guest
Posts: n/a
 
      10-20-2007
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");
...
--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Creating classes and objects more than once? Viktor Kerkez Python 15 12-02-2008 06:48 AM
get data that fills a gridviewocontrol inside it (i'm extendig the gridview) Sergio E. ASP .Net Building Controls 4 08-10-2007 12:12 PM
get data that fills a gridviewocontrol inside it (i'm extendig the gridview) Sergio E. ASP .Net 4 08-10-2007 12:12 PM
Extendig SqlMembershipprovider ManniAT ASP .Net Security 3 08-17-2006 12:14 PM
defining or not defining destructors johny smith C++ 8 07-02-2004 08:51 AM



Advertisments