extendig ruby: defining classes and creating objects from c

Discussion in 'Ruby' started by An Onymous, Oct 19, 2007.

  1. An Onymous

    An Onymous Guest

    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/.
    An Onymous, Oct 19, 2007
    #1
    1. Advertising

  2. 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
    Nobuyoshi Nakada, Oct 19, 2007
    #2
    1. Advertising

  3. An Onymous

    An Onymous Guest

    Re: extendig ruby: defining classes and creating objects fro

    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/.
    An Onymous, Oct 19, 2007
    #3
  4. Re: extendig ruby: defining classes and creating objects fro

    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
    Nobuyoshi Nakada, Oct 20, 2007
    #4
  5. An Onymous

    An Onymous Guest

    Re: extendig ruby: defining classes and creating objects fro

    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/.
    An Onymous, Oct 20, 2007
    #5
  6. An Onymous

    An Onymous Guest

    Re: extendig ruby: defining classes and creating objects fro

    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/.
    An Onymous, Oct 20, 2007
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. johny smith
    Replies:
    8
    Views:
    401
    Peter Koch Larsen
    Jul 2, 2004
  2. Sergio E.
    Replies:
    4
    Views:
    340
    Sergio E.
    Aug 10, 2007
  3. Sergio E.
    Replies:
    4
    Views:
    772
    Sergio E.
    Aug 10, 2007
  4. ManniAT

    Extendig SqlMembershipprovider

    ManniAT, May 15, 2005, in forum: ASP .Net Security
    Replies:
    3
    Views:
    151
  5. vasudevram
    Replies:
    6
    Views:
    909
    vasudevram
    Apr 24, 2013
Loading...

Share This Page