Wrapping C struct to Ruby-Collection of common programming errors
How to initialize C Struct and wrap it as Ruby class as parameter of another Ruby object? I am rewriting the memory, but don’t know, how to fix it.
Ruby code, I want to create instances of Person class and add Address variable into them, which is another class:
require_relative 'my_extension'
class Address
  def inspect
    "Replaced #inspect: "
  end
end
class Person
    def initialize
        puts "init"
    end
    def print()
        puts "Addr class #{@addr.inspect}"
    end
end
foo1=Person.new
foo1.add_address("London")
foo1.print
foo2=Person.new
foo2.add_address("Paris")
foo1.print
foo2.print
foo1.print
C code, extending Ruby:
#include 
#include "ruby.h"
struct Address {
    char * town;
};
static VALUE get_addr(VALUE self) {
    return rb_iv_get(self,"@addr");
}
static VALUE wrap_address_get_town(VALUE self) {
    struct Address * address;
    Data_Get_Struct(self, struct Address, address);
    return rb_str_new2(address->town);
}
VALUE foo_class;
VALUE address_wrapper_class;
void free_m(){
    printf("free\n");//just for test
}
void add_address_t(VALUE self,VALUE new_town){
    printf("add_address\n");
    /*init new struct and add value to it*/
    struct Address addr;
    addr.town=StringValuePtr(new_town);
    /*wrap struct*/
    VALUE wrapped_address=Data_Wrap_Struct(address_wrapper_class, 0, free_m,&addr);
    /*set it as instance variable*/
    rb_iv_set(self,"@addr",wrapped_address);
}
static VALUE foo_class_alloc(VALUE self){
    return self;
}
void Init_my_extension(){
    foo_class = rb_define_class("Person", rb_cObject);
    address_wrapper_class = rb_define_class("Address", rb_cObject);
    rb_define_method(address_wrapper_class, "town", wrap_address_get_town, 0);
    rb_define_method(foo_class, "add_address", add_address_t, 1);
}
Output produces unexpected result:
init
Addr class Replaced #inspect: 
init
Addr class Replaced #inspect:  //London expected
Addr class Replaced #inspect:  //another problem
Addr class Replaced #inspect: 
run
run
free
free