Nested Modules/Classes

Discussion in 'Ruby' started by Ken Mitchell, Apr 2, 2007.

  1. Ken Mitchell

    Ken Mitchell Guest

    I have what I feel should be a simple issue. Look at the following:

    ############################
    # Test of nested modules/classes
    ############################
    class Global
    module TestMod
    TEST = "test1"
    def print_test
    puts "test2"
    end
    end#module TestMod

    include TestMod
    puts TEST
    print_test

    end#class Global
    ##############################

    ->test1
    ->test.rb:22: undefined local variable or method 'print_test' for
    Global:Class

    Whether "Global" is a Class or a Method the same happens. However, if I
    comment out "Global" completely, out put is as expected:

    ->test1
    ->test2

    Thanks in advance.

    --
    Posted via http://www.ruby-forum.com/.
    Ken Mitchell, Apr 2, 2007
    #1
    1. Advertising

  2. On 4/2/07, Ken Mitchell <> wrote:
    > I have what I feel should be a simple issue. Look at the following:
    >
    > ############################
    > # Test of nested modules/classes
    > ############################
    > class Global
    > module TestMod
    > TEST = "test1"
    > def print_test
    > puts "test2"
    > end
    > end#module TestMod
    >
    > include TestMod


    You only include the module, therefore any methods defined in it will
    only be instance methods. By trying to call print_test from inside the
    class definition you are calling it as a class method. If you want
    print_test to also be a class method you must extend TestMod as well
    as including it.

    Basically include adds the module's methods as instance methods and
    extend adds them as class methods.

    Ryan
    Ryan Leavengood, Apr 2, 2007
    #2
    1. Advertising

  3. On Tue, Apr 03, 2007 at 06:02:41AM +0900, Ken Mitchell wrote:
    > I have what I feel should be a simple issue. Look at the following:
    >
    > ############################
    > # Test of nested modules/classes
    > ############################
    > class Global
    > module TestMod
    > TEST = "test1"
    > def print_test
    > puts "test2"
    > end
    > end#module TestMod
    >
    > include TestMod
    > puts TEST
    > print_test
    >
    > end#class Global
    > ##############################
    >
    > ->test1
    > ->test.rb:22: undefined local variable or method 'print_test' for
    > Global:Class
    >
    > Whether "Global" is a Class or a Method the same happens. However, if I
    > comment out "Global" completely, out put is as expected:
    >
    > ->test1
    > ->test2


    If you 'include' a module in a class, its methods are added as instance
    methods for objects of that class. Try:

    a = Global.new
    a.print_test
    Brian Candler, Apr 2, 2007
    #3
  4. Alle luned=C3=AC 2 aprile 2007, Ken Mitchell ha scritto:
    > I have what I feel should be a simple issue. Look at the following:
    >
    > ############################
    > # Test of nested modules/classes
    > ############################
    > class Global
    > module TestMod
    > TEST =3D "test1"
    > def print_test
    > puts "test2"
    > end
    > end#module TestMod
    >
    > include TestMod
    > puts TEST
    > print_test
    >
    > end#class Global
    > ##############################
    >
    > ->test1
    > ->test.rb:22: undefined local variable or method 'print_test' for
    > Global:Class
    >
    > Whether "Global" is a Class or a Method the same happens. However, if I
    > comment out "Global" completely, out put is as expected:
    >
    > ->test1
    > ->test2
    >
    > Thanks in advance.


    When you include TestMod in the class Global, the instance methods of TestM=
    od=20
    become instance methods of Global, that is, they become methods of the=20
    instances of Global, not of Global itself. So, you can do:

    Global.new.print_test
    =3D> "test2"

    The same happens if Global were a module.

    If you want to add the instance methods of TestMod to Global itself, instea=
    d,=20
    you can do the following:

    class Global
    module TestMod
    ...
    end #End of TestMod
    extend TestMod
    end

    While Module#include adds the instance methods of the module as instance=20
    methods of the class (or module) where it's called, extend adds the instanc=
    e=20
    methods of the module to its receiver (self, in this case).

    I hope this helps

    Stefano
    Stefano Crocco, Apr 2, 2007
    #4
  5. Ken Mitchell

    Ken Mitchell Guest

    Brian Candler wrote:
    > On Tue, Apr 03, 2007 at 06:02:41AM +0900, Ken Mitchell wrote:
    >> end
    >> ->test.rb:22: undefined local variable or method 'print_test' for
    >> Global:Class
    >>
    >> Whether "Global" is a Class or a Method the same happens. However, if I
    >> comment out "Global" completely, out put is as expected:
    >>
    >> ->test1
    >> ->test2

    >
    > If you 'include' a module in a class, its methods are added as instance
    > methods for objects of that class. Try:
    >
    > a = Global.new
    > a.print_test


    Thank you two! See, I knew it would be simple and now it even makes
    sense.

    So in the context of the above, my application will be performing a wide
    range of work and will need to be quite modular (ok I'm lazy). As far
    as preference and "best practice", how would I best layout the
    namespace. For instance:

    #/lib/testapp.rb
    #/lib/testapp/config.rb
    #/lib/testapp/logger.rb

    maybe this....

    module Testapp
    module config
    end

    class logger
    end
    end

    Looking through included source, I see this done so many different ways.
    What is the best. Thanks so much

    --
    Posted via http://www.ruby-forum.com/.
    Ken Mitchell, Apr 2, 2007
    #5
  6. Ken Mitchell

    Ken Mitchell Guest

    Sorry for the Double Post, thank you Stefano I missed you.

    Where is the mailing list located. I cannot find it, only these forums.
    It seems that some of you guys are using maillist functionality


    --
    Posted via http://www.ruby-forum.com/.
    Ken Mitchell, Apr 2, 2007
    #6
  7. Ken Mitchell

    Ilan Berci Guest

    Ken Mitchell wrote:
    > I have what I feel should be a simple issue. Look at the following:
    >
    > ############################
    > # Test of nested modules/classes
    > ############################
    > class Global
    > module TestMod
    > TEST = "test1"
    > def print_test
    > puts "test2"
    > end
    > end#module TestMod
    >
    > include TestMod
    > puts TEST
    > print_test
    >
    > end#class Global
    > ##############################
    >
    > ->test1
    > ->test.rb:22: undefined local variable or method 'print_test' for
    > Global:Class
    >
    > Whether "Global" is a Class or a Method the same happens. However, if I
    > comment out "Global" completely, out put is as expected:
    >
    > ->test1
    > ->test2
    >
    > Thanks in advance.



    irb(main):004:0> class Global
    irb(main):005:1> module TestMod
    irb(main):006:2> TEST = "test1"
    irb(main):007:2> def print_test
    irb(main):008:3> puts "test2"
    irb(main):009:3> end
    irb(main):010:2> end
    irb(main):011:1> extend TestMod
    irb(main):012:1> end
    => Global
    irb(main):013:0> Global.print_test
    test2
    => nil

    ilan


    --
    Posted via http://www.ruby-forum.com/.
    Ilan Berci, Apr 2, 2007
    #7
  8. On 4/2/07, Ken Mitchell <> wrote:
    >
    > Where is the mailing list located. I cannot find it, only these forums.
    > It seems that some of you guys are using maillist functionality


    Hi Ken,

    The Ruby Forum is useful for the occasional post. It forwards your
    messages to the ruby-talk mailing list. If you would like to subscribe
    to ruby-talk go here:

    http://www.ruby-lang.org/en/community/mailing-lists/

    You can learn a lot about Ruby by reading the messages posted here.

    Regarding your question about how to structure your Ruby code, here
    are my suggestions:

    - create a Module as the namespace for all the classes in your
    application or library.
    - create the classes you need inside that module.
    - if you find classes with common functionality, see if you can break
    that out into modules which are included in those classes.
    - I recommend using the Test::Unit library to unit test your classes.
    An example of this is in my recent Ruby Quiz submission:

    http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/246269

    Good luck with Ruby and welcome to our community. As you can see we
    are a pretty friendly and helpful bunch :)

    Regards,
    Ryan
    Ryan Leavengood, Apr 2, 2007
    #8
    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. Razvan
    Replies:
    5
    Views:
    11,275
    Dale King
    Jul 27, 2004
  2. kelvSYC
    Replies:
    2
    Views:
    581
    Chris Smith
    Aug 18, 2004
  3. Tony Johansson

    Nested classes within other classes

    Tony Johansson, Dec 14, 2004, in forum: C++
    Replies:
    2
    Views:
    469
    msalters
    Dec 14, 2004
  4. Remy Cool
    Replies:
    1
    Views:
    419
    Remy Cool
    Aug 27, 2003
  5. Chad E. Dollins
    Replies:
    3
    Views:
    648
    Kai-Uwe Bux
    Nov 8, 2005
Loading...

Share This Page