probably a dumb question about ruby extensions...

Member
Posts: 567
Joined: 2004.07
Post: #1
ok, so I'm writing a Vector class for ruby, to get my self comfortable with writing them. (codeSmile

Code:
#include "ruby.h"
#include "Vector.h"
#include <stdlib.h>

static void V3Free(void *p)
{
}

static VALUE V3Alloc(VALUE klass)
{
    Vector3 v = Vector3Zero;
    VALUE obj;
    obj = Data_Wrap_Struct(klass, 0, V3Free, &v);
}

static VALUE getX(VALUE self)
{
    Vector3 *v;
    
    Data_Get_Struct(self, Vector3, v);
    
    return rb_float_new(v->x);
}

static VALUE getY(VALUE self)
{
    Vector3 *v;
    
    Data_Get_Struct(self, Vector3, v);
    
    return rb_float_new(v->y);
}

static VALUE getZ(VALUE self)
{
    Vector3 *v;
    
    Data_Get_Struct(self, Vector3, v);
    
    return rb_float_new(v->z);
}

static VALUE rbVector3Initialize(VALUE self, VALUE x, VALUE y, VALUE z)
{
    Vector3 *v;
    
    Data_Get_Struct(self, Vector3, v);
    
    v->x = (float)NUM2DBL(x);
    v->y = (float)NUM2DBL(y);
    v->z = (float)NUM2DBL(z);

    return self;
}

VALUE rbVector3Object;

void Init_Vector()
{
    rbVector3Object = rb_define_class("Vector3", rb_cObject);
    rb_define_alloc_func(rbVector3Object, V3Alloc);
    rb_define_method(rbVector3Object, "initialize", rbVector3Initialize, 3);
    rb_define_method(rbVector3Object, "x", getX, 0);
    rb_define_method(rbVector3Object, "y", getY, 0);
    rb_define_method(rbVector3Object, "z", getZ, 0);
}

and the ruby file:

Code:
require 'Vector'

v = Vector3.new(1, 2, 3)

puts "X: " + v.x.to_s + "\n"
puts "Y: " + v.y.to_s + "\n"
puts "Z: " + v.z.to_s + "\n"

the problem is, it prints Z as zero. Am I doing this all wrong? What's the problem?

It's not magic, it's Ruby.
Quote this message in a reply
Member
Posts: 567
Joined: 2004.07
Post: #2
if you want the original vector structure and functions, I can post them too.... Vector3Zero is simply a #define Vector3Zero Vector3Create, which DOESN't return a pointer.

It's not magic, it's Ruby.
Quote this message in a reply
Sage
Posts: 1,482
Joined: 2002.09
Post: #3
Your allocation function is wrong.

One way to do it would be:
Code:
static VALUE V3Alloc(VALUE klass)
{
    Vector3 *v =  calloc(1, sizeof(Vector3);
    return Data_Wrap_Struct(klass, 0, free, &v);
}

For one, you need to wrap a pointer to somewhere on the heap. Doing otherwise is a really bad idea. Data_Wrap_Struct() retains that pointer, it doesn't copy it. Also, you weren't actually returning anything. I'm surprised that didn't crash horribly.

Just a Ruby hint: Do you know about string interpolation? It looks like you are writing Java code with your puts statements. An easier way would be to do this:
Code:
puts "X: #{v.x}"
In a double quoted string, you can add #{}'s and put code inside them. The result automatically has #to_s called on it. Also, #puts prints a string with a newline for you. #print prints a string as is.

Scott Lembcke - Howling Moon Software
Author of Chipmunk Physics - A fast and simple rigid body physics library in C.
Quote this message in a reply
Member
Posts: 567
Joined: 2004.07
Post: #4
wow, I never realizzed you could do that 0.0 (about the quotes). Very useful.

oh, and it works. Thanks for that!

It's not magic, it's Ruby.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Ruby on Rails setting Time to NULL BeyondCloister 3 3,913 Nov 21, 2007 09:56 AM
Last Post: AndyKorth
  Ruby, MacPorts, Firewalls BeyondCloister 3 4,105 Nov 6, 2007 04:57 PM
Last Post: OneSadCookie
  Ruby: Resources for Learning iefan 10 6,953 Jul 4, 2007 08:54 AM
Last Post: ALX99066
  Ruby Gems and OpenGL Jaden 2 3,090 Apr 2, 2007 01:15 AM
Last Post: Jaden
  Embedding Ruby DesertPenguin 3 3,453 Jan 5, 2007 09:11 PM
Last Post: DesertPenguin