# Extendig ruby: defining classes and creating objects from c

**URL:** <https://www.ruby-forum.com/t/extendig-ruby-defining-classes-and-creating-objects-from-c/117716>\
**Category:** Ruby\
**Created:** [October 19, 2007, 5:56pm UTC](https://www.ruby-forum.com/t/extendig-ruby-defining-classes-and-creating-objects-from-c/117716 "2007-10-19T17:56:16Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![libit](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/8baadc/32.png) [@libit](https://www.ruby-forum.com/u/libit)\
**Post date:** [October 19, 2007, 5:56pm UTC](https://www.ruby-forum.com/t/extendig-ruby-defining-classes-and-creating-objects-from-c/117716/1 "2007-10-19T17:56:16Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![libit](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/8baadc/32.png) [@libit](https://www.ruby-forum.com/u/libit)\
**Post date:** [October 19, 2007, 6:23pm UTC](https://www.ruby-forum.com/t/extendig-ruby-defining-classes-and-creating-objects-from-c/117716/2 "2007-10-19T18:23:48Z")

</div>

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);
```

---

<div class="post-metadata">

**Author:** ![libit](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/8baadc/32.png) [@libit](https://www.ruby-forum.com/u/libit)\
**Post date:** [October 20, 2007, 1:56am UTC](https://www.ruby-forum.com/t/extendig-ruby-defining-classes-and-creating-objects-from-c/117716/3 "2007-10-20T01:56:18Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![libit](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/8baadc/32.png) [@libit](https://www.ruby-forum.com/u/libit)\
**Post date:** [October 20, 2007, 5:40am UTC](https://www.ruby-forum.com/t/extendig-ruby-defining-classes-and-creating-objects-from-c/117716/4 "2007-10-20T05:40:21Z")

</div>

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 " raising a  
RuntimeError with the given message  
myrb\_raise(exc,NULL) behaves like "raise " 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 ,” 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);  
}

---

<div class="post-metadata">

**Author:** ![libit](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/8baadc/32.png) [@libit](https://www.ruby-forum.com/u/libit)\
**Post date:** [October 20, 2007, 5:52am UTC](https://www.ruby-forum.com/t/extendig-ruby-defining-classes-and-creating-objects-from-c/117716/5 "2007-10-20T05:52:29Z")

</div>

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”);  
…

---

<div class="post-metadata">

**Author:** ![libit](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/l/8baadc/32.png) [@libit](https://www.ruby-forum.com/u/libit)\
**Post date:** [October 19, 2007, 9:33pm UTC](https://www.ruby-forum.com/t/extendig-ruby-defining-classes-and-creating-objects-from-c/117716/6 "2007-10-19T21:33:31Z")

</div>

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
