class A::B verses module A ; class B

Discussion in 'Ruby' started by Jeff Mitchell, Jun 5, 2004.

  1. 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.
     
    Jeff Mitchell, Jun 5, 2004
    #1
    1. Advertising

  2. Extending in C: need to use a non-basic class defined in Ruby inmy C code

    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
     
    Austin McDonald, Jun 5, 2004
    #2
    1. Advertising

  3. Jeff Mitchell

    daz Guest

    Re: Extending in C: need to use a non-basic class defined in Ruby in my C code

    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 :)
    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 ;-)


    daz
     
    daz, Jun 5, 2004
    #3
  4. Jeff Mitchell

    daz Guest

    Re: Extending in C: need to use a non-basic class defined in Ruby in my C code

    I wrote:
    > Seemless beauty is what you'll find :)


    <gasps>

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

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


    daz
     
    daz, Jun 5, 2004
    #4
  5. Re: Extending in C: need to use a non-basic class defined in Rubyin my C code

    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 :) ) 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 :)
    >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 ;-)
    >
    >
    >daz
    >
    >
    >
    >
    >
    >
    >
     
    Austin McDonald, Jun 5, 2004
    #5
  6. Re: Extending in C: need to use a non-basic class defined in Rubyin my C code

    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 :)
    >>
    >>

    >
    ><gasps>
    >
    >Seamless, not seemless (which has a completely unintended meaning)
    >
    >I can spell correctly only /after/ posting (and sleep).
    >
    >
    >daz
    >
    >
    >
    >
    >
    >
    >
     
    Austin McDonald, Jun 5, 2004
    #6
  7. Jeff Mitchell

    daz Guest

    Re: Extending in C: need to use a non-basic class defined in Ruby in my C code

    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 :)
    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 :) )


    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
     
    daz, Jun 5, 2004
    #7
  8. Jeff Mitchell

    Kent Dahl Guest

    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.

    http://rubytalk.com/78843

    --
    (\[ Kent Dahl ]/)_ _~_ _____[ http://www.pvv.org/~kentda/ ]_____/~
    ))\_student_/(( \__d L b__/ Master of Science in Technology )
    ( \__\_õ|õ_/__/ ) _) Industrial economics and technology management (
    \____/_ö_\____/ (____engineering.discipline_=_Computer::Technology___)
     
    Kent Dahl, Jun 5, 2004
    #8
  9. On Saturday, June 5, 2004, 7:58:48 PM, Kent wrote:

    > 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.


    > http://rubytalk.com/78843


    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
     
    Gavin Sinclair, Jun 5, 2004
    #9
  10. Re: Extending in C: need to use a non-basic class defined in Rubyin my C code

    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 :)
    > 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.
     
    Joel VanderWerf, Jun 5, 2004
    #10
  11. Jeff Mitchell

    daz Guest

    Re: Extending in C: need to use a non-basic class defined in Ruby in my C code

    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
     
    daz, Jun 5, 2004
    #11
  12. Problems with Ruby GC'ing a variable I'm using.

    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
     
    Austin McDonald, Jun 6, 2004
    #12
  13. Jeff Mitchell

    ts Guest

    Re: Problems with Ruby GC'ing a variable I'm using.

    >>>>> "A" == Austin McDonald <> writes:

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

    Your mark function is wrong, you must write it

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

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


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

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

    A> Population* p = ALLOC(Population);
    A> /* do some stuff to the struct*/
    A> 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')


    A> VALUE argv[3];



    Guy Decoux
     
    ts, Jun 6, 2004
    #13
  14. Re: Problems with Ruby GC'ing a variable I'm using.

    Thanks; sorry about the neophyte question.

    Austin

    ts wrote:

    >>>>>>"A" == Austin McDonald <> writes:
    >>>>>>
    >>>>>>

    >
    >A> In this code snippet, p->popArray is the one getting GC'd. My mark
    >A> function only does this:
    >
    > Your mark function is wrong, you must write it
    >
    >A> void pop_mark(VALUE self) {
    >A> Population* p;
    >A> Data_Get_Struct(self, Population, p);
    >A> rb_gc_mark(p->popArray);
    >A> }
    >
    > void pop_mark(Population *)
    > {
    > rb_gc_mark(p->popArray);
    > }
    >
    >
    >A> VALUE
    >A> pop_new(VALUE class, VALUE size, VALUE tagsize, VALUE strategysize) {
    >
    > it's best if you use the scheme allocate/initialize rather than new
    >
    >A> Population* p = ALLOC(Population);
    >A> /* do some stuff to the struct*/
    >A> 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')
    >
    >
    >A> VALUE argv[3];
    >
    >
    >
    >Guy Decoux
    >
    >
    >
    >
    >
     
    Austin McDonald, Jun 6, 2004
    #14
    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. wh
    Replies:
    2
    Views:
    605
    Cowboy \(Gregory A. Beamer\)
    Jan 16, 2004
  2. Leon
    Replies:
    4
    Views:
    400
  3. Hoffmania
    Replies:
    1
    Views:
    941
    =?Utf-8?B?Y2xpY2tvbg==?=
    Mar 29, 2006
  4. Karl Mueller
    Replies:
    1
    Views:
    1,946
    Karl Mueller
    Jan 8, 2004
  5. Jason Lillywhite
    Replies:
    2
    Views:
    116
    Jason Lillywhite
    Jan 22, 2009
Loading...

Share This Page