The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
Type checks in C extensions

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Daniel Berger

Posts: 1383
Nickname: djberg96
Registered: Sep, 2004

Daniel Berger is a Ruby Programmer who also dabbles in C and Perl
Type checks in C extensions Posted: Feb 23, 2005 8:14 AM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Daniel Berger.
Original Post: Type checks in C extensions
Feed Title: Testing 1,2,3...
Feed URL: http://djberg96.livejournal.com/data/rss
Feed Description: A blog on Ruby and other stuff.
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Daniel Berger
Latest Posts From Testing 1,2,3...

Advertisement
Occasionally you want to check the type of an argument within your C extension. I do this to avoid potentially bizarre and fatal error messages, bad data and even core dumps. Things that won't make any sense to an end user.

Let's say we have a class Bar, with a singleton method "getnum" that looks like this:
/* Take a number, multiply it by 3, return it */
static VALUE getnum(VALUE rbVal){
   int x = 0;
   x = FIX2INT(rbVal) * 3;
   return FIX2INT(x);
}

With this code Bar.getnum(10) will return 30. What will happen if I do Bar.getnum("a")? In my test, the result was 1592196. Not exactly what we were expecting.

There are a few ways you can check an object's type within a C extension. One way is to use the TYPE macro function, and check it explicitly.
if(TYPE(rbVal) != T_FIXNUM)
   rb_raise(rb_eTypeError,"argument must be a fixnum");

Another option is to use one of the builtin type check boolean macros (or whatever you want to call them).
if(!FIXNUM_P(rbVal))
   rb_raise(rb_eTypeError,"argument must be a fixnum");

But that's still too much typing if all you want is an automatic failure if it's not a Fixnum. The best and easiest solution is to use one of the "NUM" functions.
x = NUM2INT(rbVal) * 3;

Functions like INT2NUM, LONG2NUM, NUM2INT, etc, automatically include a type check and raise a TypeError if they fail. While this example actually converts and assigns a value to 'x', there are times when I use it in void context strictly as a type checking mechanism.
NUM2INT(rbSomeVal); /* Make sure it's a Fixnum */

Note that the builtin type check is a wee bit slower than it's non type checking cousin. I generally don't type check when I'm converting C data types to Ruby objects in cases where I absolutely know that the return value is an integer.

Read: Type checks in C extensions

Topic: So What If RedHanded's Snazzy New Wiki Is Only For Vim? Previous Topic   Next Topic Topic: The case against high-level components

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use