Class A::B verses module A ; class B

module A
   FOO = 99
end

module A
   class B
      puts "FOO is #{FOO}" # => "FOO is 99"
   end
end

class A::B
   puts "FOO is #{FOO}" # error
end

Comments? I assumed the two forms were equivalent until I ran into
this. Is there a reason they should be different? I prefer the
second form, if only to save some indentation space.

Hi, I'm attempting to transfer some intensive functions from Ruby to C, but I'd like to put as little of my code in C as possible. So, I'm trying to access a class defined entirely in Ruby from my C code. Specifically, I need to create an instance of this class (called Population) and access some of its methods. A few questions about this:

1) Do the functions I need to use have to be implemented in C as well, or can I access their "ruby version" using some C functions? What C functions do I need to use to do this?

2) Is there a decent C API document anywhere? I've read through "Programming Ruby," and its chapter on extending in C seems adequate for getting started, but leaves out a lot and simply refers one to the horribly unreadable header files, which give little to no indication as to what each function does.

And, on a related note:

3) What kind of IDE have you found to be good for co-development of Ruby/C code? I'm currently working with Dev-C++ (www.bloodshed.net), and with some tweaking it seems usable. Is there anything better?

Thanks very much,
Austin McDonald

Jeff Mitchell wrote:

module A
   FOO = 99
end

module A
   class B
      puts "FOO is #{FOO}" # => "FOO is 99"
   end
end

class A::B
   puts "FOO is #{FOO}" # error
end

Comments? I assumed the two forms were equivalent until I ran into
this. Is there a reason they should be different? I prefer the
second form, if only to save some indentation space.

I'm on the "hope it's a feature" side on this one. It means you have to explicitly open namespaces you want to use, and the A::B shortcut notation only opens the last namespace.

Some of this has already been discussed in the thread
"Nested class/module namespace", see [rubytalk:78843] for Matz' answer.

···

--
(\[ Kent Dahl ]/)_ _~_ _____[ Kent Dahl - Kent Dahl ]_____/~
  ))\_student_/(( \__d L b__/ Master of Science in Technology )
( \__\_õ|õ_/__/ ) _) Industrial economics and technology management (
  \____/_ö_\____/ (____engineering.discipline_=_Computer::Technology___)

Austin McDonald wrote:

Hi, I'm attempting to transfer some intensive functions from Ruby to C,
but I'd like to put as little of my code in C as possible. So, I'm
trying to access a class defined entirely in Ruby from my C code.
Specifically, I need to create an instance of this class (called
Population) and access some of its methods. A few questions about this:

1) Do the functions I need to use have to be implemented in C as well,
or can I access their "ruby version" using some C functions? What C
functions do I need to use to do this?

Seemless beauty is what you'll find :slight_smile:
Define an empty class (if its name is known) in the Init_foo part of
your extension - look at any other extension to get clues (rb_define_class).

Reopen your class (looks the same as a class definition) and define
your methods inside it (all in Ruby):

class Foo
  def a
    # whatever
  end

  def b
  end
end

Call them from C using the rb_funcall family.

2) Is there a decent C API document anywhere? I've read through
"Programming Ruby," and its chapter on extending in C seems adequate for
getting started, but leaves out a lot and simply refers one to the
horribly unreadable header files, which give little to no indication as
to what each function does.

Co-author of "Programming Ruby," (and so much more relating to Ruby)
Dave Thomas has documented the API in the .c files if you grab a
reasonably up-to-date copy of the source distribution.

And, on a related note:

3) What kind of IDE have you found to be good for co-development of
Ruby/C code? I'm currently working with Dev-C++ (www.bloodshed.net),
and with some tweaking it seems usable. Is there anything better?

Ooooh, that was sneaky; you just want to ensure that this thread
grows to 35+ replies, but the downside is that no-one gets round
to answering your main questions.
My answer is: You /know/ there are better IDE's that Dev-C++, even free
ones, but there isn't just one for Ruby and I use a low-priced
shareware one on Windows which is an anagram of UtralEdti and has
ctag support, macros, blah ... Everyone else uses their favourite
and they're all better than mine, OK.

Thanks very much,

Thank you for choosing Ruby :wink:

daz

Jeff Mitchell wrote:

module A
   FOO = 99
end

module A
   class B
      puts "FOO is #{FOO}" # => "FOO is 99"
   end
end

class A::B
   puts "FOO is #{FOO}" # error
end

Comments? I assumed the two forms were equivalent until I ran into
this. Is there a reason they should be different? I prefer the
second form, if only to save some indentation space.

I'm on the "hope it's a feature" side on this one. It means you have to
explicitly open namespaces you want to use, and the A::B shortcut
notation only opens the last namespace.

I dislike the behaviour displayed above. But your explanation for it
is quite reasonable.

Some of this has already been discussed in the thread
"Nested class/module namespace", see [rubytalk:78843] for Matz' answer.

| RubyTalk

I think in Ruby 2.0 there will be a change in the way constants are
resolved (see Matz's slides, wherever they lay). That would most
likely mean that how you arrived at a particular namespace is
irrelevant.

Gavin

···

On Saturday, June 5, 2004, 7:58:48 PM, Kent wrote:

Thanks for the excellent reply - I was thinking I'd have to do something along those lines. I'm pleased to know that it works, though, and that it's fairly intuitive. And thanks for the tip on the source code; I'm sure it'll be useful in the future. (I'm sure these jokes have all been made by this point, but Dave Thomas? Isn't he the founder of Wendy's?)

And it wasn't my intention to start a lengthy thread about IDEs; I was just hoping for something that could do both Ruby and C with equal skill, or even in the same IDE, (or really, anything decent for Ruby at all :slight_smile: ) Oh well, it'll give the night-owls like myself something to post about when they can't sleep.

As I guess is apparent from my questions, I'm pretty new to Ruby, and I've been very impressed with how easy it is to do things in this language. My only complaint (thus far) is the insane slowness; hence, my desire to write C extensions. Hopefully that route will pan out for me.

Thanks again,
Austin McDonald

daz wrote:

···

Austin McDonald wrote:

Hi, I'm attempting to transfer some intensive functions from Ruby to C,
but I'd like to put as little of my code in C as possible. So, I'm
trying to access a class defined entirely in Ruby from my C code.
Specifically, I need to create an instance of this class (called
Population) and access some of its methods. A few questions about this:

1) Do the functions I need to use have to be implemented in C as well,
or can I access their "ruby version" using some C functions? What C
functions do I need to use to do this?

Seemless beauty is what you'll find :slight_smile:
Define an empty class (if its name is known) in the Init_foo part of
your extension - look at any other extension to get clues (rb_define_class).

Reopen your class (looks the same as a class definition) and define
your methods inside it (all in Ruby):

class Foo
def a
   # whatever
end

def b
end
end

Call them from C using the rb_funcall family.

2) Is there a decent C API document anywhere? I've read through
"Programming Ruby," and its chapter on extending in C seems adequate for
getting started, but leaves out a lot and simply refers one to the
horribly unreadable header files, which give little to no indication as
to what each function does.

Co-author of "Programming Ruby," (and so much more relating to Ruby)
Dave Thomas has documented the API in the .c files if you grab a
reasonably up-to-date copy of the source distribution.

And, on a related note:

3) What kind of IDE have you found to be good for co-development of
Ruby/C code? I'm currently working with Dev-C++ (www.bloodshed.net),
and with some tweaking it seems usable. Is there anything better?
   
Ooooh, that was sneaky; you just want to ensure that this thread
grows to 35+ replies, but the downside is that no-one gets round
to answering your main questions.
My answer is: You /know/ there are better IDE's that Dev-C++, even free
ones, but there isn't just one for Ruby and I use a low-priced
shareware one on Windows which is an anagram of UtralEdti and has
ctag support, macros, blah ... Everyone else uses their favourite
and they're all better than mine, OK.

Thanks very much,

Thank you for choosing Ruby :wink:

daz

I wrote:

Seemless beauty is what you'll find :slight_smile:

<gasps>

Seamless, not seemless (which has a completely unintended meaning)

I can spell correctly only /after/ posting (and sleep).

daz

daz wrote:

Austin McDonald wrote:

Hi, I'm attempting to transfer some intensive functions from Ruby to C,
but I'd like to put as little of my code in C as possible. So, I'm
trying to access a class defined entirely in Ruby from my C code.
Specifically, I need to create an instance of this class (called
Population) and access some of its methods. A few questions about this:

1) Do the functions I need to use have to be implemented in C as well,
or can I access their "ruby version" using some C functions? What C
functions do I need to use to do this?

Seemless beauty is what you'll find :slight_smile:
Define an empty class (if its name is known) in the Init_foo part of
your extension - look at any other extension to get clues (rb_define_class).

Reopen your class (looks the same as a class definition) and define
your methods inside it (all in Ruby):

class Foo
  def a
    # whatever
  end

  def b
  end
end

Call them from C using the rb_funcall family.

This isn't going to help much, if at all, with the speed of these calls, since it still goes thru the usual method lookup. Maybe that's ok, if the bottleneck is not these calls, but the code around them.

If you want to avoid the overhead of method calls, you have to trade away the flexibility of method lookup. The ruby source has many nice models for doing this. For instance, the method Array#push (in array.c) is callable from C code in (at least) two ways:

   ID id_push = rb_intern("push");
   rb_funcall(ary, id_push, 1, item);

and

   rb_ary_push(ary, item);

The former goes thru the usual lookup. The latter skips directly to the C function which implements push.

If you want objects of your class to be efficiently accessible from C, you may also want to use the DATA type, so that you don't have to look up instance variables, but can directly access the underlying struct. That's no longera class defined entirely in ruby, though.

Yeah, caught that - hilarious that that small of a typo makes a decent sentence, yet such a totally different meaning. I love English :).

Austin

daz wrote:

···

I wrote:

Seemless beauty is what you'll find :slight_smile:
   
<gasps>

Seamless, not seemless (which has a completely unintended meaning)

I can spell correctly only /after/ posting (and sleep).

daz

Austin McDonald wrote:

I'm sure these jokes have all been made by this point, but Dave Thomas?
Isn't he the founder of Wendy's?

I think he's everything except that :slight_smile:
I have a feeling he's away atm, but if he was near his laptop
he wouldn't be afraid to use it.
(Haven't heard that in the UK, anyway)

And it wasn't my intention to start a lengthy thread about IDEs; I was
just hoping for something that could do both Ruby and C with equal
skill, or even in the same IDE, (or really, anything decent for Ruby at
all :slight_smile: )

Ah, both. Can't spell or read now.
To be honest, I use Ruby Development Environment (RDE - Windows only)
for Ruby and UE for C.

As I guess is apparent from my questions, I'm pretty new to Ruby, and
I've been very impressed with how easy it is to do things in this
language. My only complaint (thus far) is the insane slowness ...

Nooo, you've done it again, that'll be high 70's in replies.

Have to leave you to the wolves: I'm the only nice person here --
(apart from the rest).

cheers,

daz

Joel VanderWerf wrote:

daz wrote:
> Austin McDonald wrote:
>
>>1) Do the functions I need to use have to be implemented in C as well,
>>or can I access their "ruby version" using some C functions? What C
>>functions do I need to use to do this?
>>
>
> Define an empty class (if its name is known) in the Init_foo part of
> your extension - look at any other extension to get clues (rb_define_class).
>
> Reopen your class (looks the same as a class definition) and define
> your methods inside it (all in Ruby):
>
> class Foo
> def a
> # whatever
> end
>
> def b
> end
> end
>
> Call them from C using the rb_funcall family.

This isn't going to help much, if at all, with the speed of these calls,
since it still goes thru the usual method lookup. Maybe that's ok, if
the bottleneck is not these calls, but the code around them.

I should have said that. To gain any speed benefit from the extension,
you'd have to cut the intensive bits out of Ruby code and write them in C.

You might use rb_define_method() / rb_define_singleton_method() when
building your class instead of creating an empty class.

More help on the Ruby API is in README.EXT in the source distro.

···

-----

The profile library (described in Programming Ruby under "Standard Libraries")
can help you to track down where the bottlenecks are in your Ruby script and
you should be able to find ways of reducing the need for C.

  require 'profile' # at the top of your script

With experience, you'll find ways to avoid making Ruby do unnecessary,
time-consuming work like object duplication.

daz

Thanks for all the help with my last set of questions.

I'm writing a function in my C extension where I copy a variable from my object structure to a temporary location. Then, I put a new instance in the new location. However, Ruby keeps garbage collecting the new variable. I fixed this error by disabling GC for awhile, then re-enabling it when I'm done. Is there a nicer way to do that?

Code snippet:

static VALUE
pop_reproduce(VALUE self, VALUE payoffs) {
    rb_gc_disable();
    Population* p;
    Data_Get_Struct(self, Population, p);

    VALUE oldArray = p->popArray;
    p->popArray = rb_ary_new2(p->size);
       /*...do some stuff...*/

    rb_gc_enable();
    return self;
}

In this code snippet, p->popArray is the one getting GC'd. My mark function only does this:

void pop_mark(VALUE self) {
    Population* p;
    Data_Get_Struct(self, Population, p);
    rb_gc_mark(p->popArray);
}

It's possible that popArray isn't what is getting GC'ed; did I write the mark function wrong? Here's where I register the mark function:

VALUE
pop_new(VALUE class, VALUE size, VALUE tagsize, VALUE strategysize) {
    Population* p = ALLOC(Population);
    /* do some stuff to the struct*/
    VALUE obj = Data_Wrap_Struct(class, pop_mark, free, p);
    VALUE argv[3];
    argv[0]=size;
    argv[1]=tagsize;
    argv[2]=strategysize;
    rb_obj_call_init(obj, 3, argv);
    return obj;
}

Anyway, I realize that's a lot of code to paste... I'm just wondering if there's any way to fix this short of actually disabling the GC.

Thanks,
Austin McDonald

In this code snippet, p->popArray is the one getting GC'd. My mark
function only does this:

Your mark function is wrong, you must write it

void pop_mark(VALUE self) {
    Population* p;
    Data_Get_Struct(self, Population, p);
    rb_gc_mark(p->popArray);
}

   void pop_mark(Population *)
   {
       rb_gc_mark(p->popArray);
   }

VALUE
pop_new(VALUE class, VALUE size, VALUE tagsize, VALUE strategysize) {

  it's best if you use the scheme allocate/initialize rather than new

    Population* p = ALLOC(Population);
    /* do some stuff to the struct*/
    VALUE obj = Data_Wrap_Struct(class, pop_mark, free, p);

best to use Data_Make_Struct

       obj = Data_Make_Struct(class, Population, pop_mark, free, p);

the advantage is that p will be filled with zero, it's important for the
GC (try to avoid the variable name `class')

    VALUE argv[3];

Guy Decoux

Thanks; sorry about the neophyte question.

Austin

ts wrote:

···

"A" == Austin McDonald <austin-mcdonald@utulsa.edu> writes:
           
In this code snippet, p->popArray is the one getting GC'd. My mark function only does this:

Your mark function is wrong, you must write it

void pop_mark(VALUE self) {
    Population* p;
    Data_Get_Struct(self, Population, p);
    rb_gc_mark(p->popArray);
}

  void pop_mark(Population *)
  {
      rb_gc_mark(p->popArray);
  }

VALUE
pop_new(VALUE class, VALUE size, VALUE tagsize, VALUE strategysize) {

it's best if you use the scheme allocate/initialize rather than new

    Population* p = ALLOC(Population);
    /* do some stuff to the struct*/
    VALUE obj = Data_Wrap_Struct(class, pop_mark, free, p);

best to use Data_Make_Struct

      obj = Data_Make_Struct(class, Population, pop_mark, free, p);

the advantage is that p will be filled with zero, it's important for the
GC (try to avoid the variable name `class')

    VALUE argv[3];

Guy Decoux