howto make something like Errno::##, for my C ext, or do I need to?

S

Sam Roberts

I'm wrapping a library, it returns its errors as numbers (many of them,
too many to wrap even automatically), and I don't know how to raise
exceptions.

I've looked at how ruby deals with unix error numbers. I guess I
could cut-n-paste all the code to that my extension does the same... but
that seems wrong, somehow.

What I'd really like to do is have only one error class, but raise
objects as exceptions, with the objects @errno set to the value,
I'd do this in ruby like this:

class MyErr < StandardError
attr_reader :eno
def initialize(eno); @eno = eno; end
end


...
raise MyError.new(35)

Looking at the exception raising APIs in README.EXT, I can't quite see
how to do this.


Does anybody have any suggestions?

Thanks a lot,
Sam
 
C

Charles Mills

Sam said:
I'm wrapping a library, it returns its errors as numbers (many of them,
too many to wrap even automatically), and I don't know how to raise
exceptions.

I've looked at how ruby deals with unix error numbers. I guess I
could cut-n-paste all the code to that my extension does the same... but
that seems wrong, somehow.

What I'd really like to do is have only one error class, but raise
objects as exceptions, with the objects @errno set to the value,
I'd do this in ruby like this:

class MyErr < StandardError
attr_reader :eno
def initialize(eno); @eno = eno; end
end


...
raise MyError.new(35)

Looking at the exception raising APIs in README.EXT, I can't quite see
how to do this.

In short:
rb_exc_raise(my_err_new(eno));

You probably want to have the ability to add a message to your error
objects so you may want to do:
rb_exc_raise(my_err_new("msg", eno));

or define a function like

static void
raise_my_err(int eno, const char *fmt, ...)
{
va_list args;
char buf[BUFSIZ];

va_init_list(args, fmt);
vsnprintf(buf, BUFSIZ, fmt, args);
va_end(args);
rb_exc_raise(my_err_new(buf, eno));
}

most of the above is a copy and paste from code in error.c. I think
your new function would look something like this:

static VALUE
my_err_new(const char *buf, int eno)
{
VALUE self = rb_exc_new2(cMyErr, buf);
rb_iv_set(self, "@eno", INT2FIX(eno));
return self;
}

-Charlie
 

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

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top