Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby Classes within Classes (or Modules within Modules)

Tags:

ruby

As I'm reading different Ruby books, I've noticed that Ruby classes can be defined within other Ruby classes or modules. Here's an example of a class within a class:

class Outerclass   def foobar     puts "FOOBAR"   end    class Innerclass        def barfoo       puts "BARFOO"     end   end end 

Here's some code that I ran in IRB to try to understand this conceptually:

oc = Outerclass.new # => #<Outerclass:0x00000100a46478>  Outerclass.instance_methods(false) # => [:foobar]  ic = Outerclass::Innerclass.new # => #<Outerclass::Innerclass:0x00000100a0b120>  ic = Outerclass::Innerclass.instance_methods(false) # => [:barfoo] 

Here are my questions:

  1. When the ruby interpreter first encounters my Class definition code above, does it go through the methods I've written and store it somewhere? I know that the instance method "foobar" doesn't actually get run since there's no call being made to it within the Outerclass definition.

  2. Piggybacking off the 1st question, what about when Ruby encounters the class Innerclass? What happens here?

  3. In general, what are some reasons why you would want to have classes within classes? Are there any advantages to doing this?

  4. Does an instance of Outerclass know anything about the class Innerclass?

  5. Does an instance of Innerclass know anything about the class Outerclass?

Appreciate any help you can provide!

like image 512
wmock Avatar asked Feb 06 '13 21:02

wmock


People also ask

What is difference between module and class in Ruby?

What is the difference between a class and a module? Modules are collections of methods and constants. They cannot generate instances. Classes may generate instances (objects), and have per-instance state (instance variables).

Can we instantiate a class inside a module?

No, you can't instantiate a module inside a class. Module are static objects that are instantiated before time 0 during elaboration.

Can we define a class inside a class in Ruby?

Nesting class definitions in Ruby is a matter of preference, but it serves a purpose in the sense that it more strongly enforces a contract between the two classes and in doing so conveys more information about them and their uses. But to the Ruby interpreter, it's only a difference in name.

Can a module contain a class Ruby?

A Ruby module can contain classes and other modules, which means you can use it as a namespace.


1 Answers

When the interpreter is going through this file, it is assigning classes like this:

OuterClass = Class.new do    def foobar     puts "FOOBAR"   end    InnerClass = Class.new do        def barfoo       puts "BARFOO"     end   end end 

So when Ruby encounters the nested class, it assigns it to constant InnerClass which is assigned to constant OuterClass They have no relation to each other whatsoever.

The InnerClass has no inheritance to OuterClass:

  InnerClass.ancestors   => [InnerClass, Object, Kernel, BasicObject] 

When you call OuterClass::InnerClass constant you are refering to the InnerClass constant that is namespaced under the OuterClass contstant which equals the Class.new statement assigned to it.

A good book to read about this is "Metaprogramming Ruby". It goes into the details of classes, singletons, modules etc.

like image 197
Michael Papile Avatar answered Oct 02 '22 23:10

Michael Papile