When to use nested classes and classes nested in modules? - ruby

I'm pretty familiar with when to use subclasses and modules, but more recently I've been seeing nested classes like this:
class Foo
class Bar
# do some useful things
end
end
As well as classes nested in modules like so:
module Baz
class Quux
# more code
end
end
Either documentation and articles are sparse or I'm not educated on the subject enough to grope for the right search terms, but I can't seem to locate much information on the topic.
Could somebody provide examples or links to posts on why/when those techniques would be used?

Other OOP languages have inner classes which cannot be instantiated without being bound to an upper level class. For instance, in Java,
class Car {
class Wheel { }
}
only methods in the Car class can create Wheels.
Ruby doesn’t have that behaviour.
In Ruby,
class Car
class Wheel
end
end
differs from
class Car
end
class Wheel
end
only in the name of the class Wheel vs. Car::Wheel. This difference in name can make explicit to programmers that the Car::Wheel class can only represent a car wheel, as opposed to a general wheel. 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.
As for your second observation, classes nested inside of modules are generally used to namespace the classes. For instance:
module ActiveRecord
class Base
end
end
differs from
module ActionMailer
class Base
end
end
Although this is not the only use of classes nested inside of modules, it is generally the most common.

In Ruby, defining a nested class is similar to defining a class in a module. It doesn't actually force an association between the classes, it just makes a namespace for the constants. (Class and Module names are constants.)
The accepted answer wasn't correct about anything. In the example below I create an instance of the lexically enclosed class without an instance of the enclosing class ever existing.
class A; class B; end; end
A::B.new
The advantages are the same as those for modules: encapsulation, grouping code used in only one place, and placing code closer to where it is used. A large project might have one outer module that occurs over and over in each source file and contains a lot of class definitions. When the various frameworks and library codes all do this, then they contribute only one name each to the top level, reducing the chance of conflicts. Prosaic, to be sure, but that's why they are used.
Using a class instead of a module to define the outer namespace might make sense in a one-file program or script, or if you already use the top level class for something, or if you are actually going to add code to link the classes together in true inner-class style. Ruby doesn't have inner classes but nothing stops you from creating about the same behavior in code. Referencing the outer objects from the inner ones will still require dotting in from the instance of the outer object but nesting the classes will suggest that this is what you might be doing. A carefully modularized program might always create the enclosing classes first, and they might reasonably be decomposed with nested or inner classes. You can't call new on a module.
You can use the general pattern even for scripts, where the namespace isn't terribly needed, just for fun and practice...
#!/usr/bin/env ruby
class A
class Realwork_A
...
end
class Realwork_B
...
end
def run
...
end
self
end.new.run

You probably want to use this to group your classes into a module. Sort of a namespace thing.
for example the Twitter gem uses namespaces to achieve this:
Twitter::Client.new
Twitter::Search.new
So both Client and Search classes live under the Twitter module.
If you want to check the sources, the code for both classes can be found here and here.
Hope this helps!

There is yet another difference between nested classes and nested modules in Ruby prior to 2.5 that other answers failed to cover that I feel must be mentioned here. It is the lookup process.
In short: due to top level constant lookup in Ruby prior to 2.5, Ruby may end up looking for your nested class in the wrong place (in Object in particular) if you use nested classes.
In Ruby prior to 2.5:
Nested class structure:
Suppose you have a class X, with nested class Y, or X::Y. And then you have a top level class named also Y. If X::Y is not loaded, then following happens when you call X::Y:
Having not found Y in X, Ruby will try to look it up in ancestors of X. Since X is a class and not a module, it has ancestors, among which are [Object, Kernel, BasicObject]. So, it tries to look for Y in Object, where it finds it successfully.Yet it is the top level Y and not X::Y.
You will get this warning:
warning: toplevel constant Y referenced by X::Y
Nested module structure:
Suppose in the previous example X is a module and not a class.A module only has itself as ancestor: X.ancestors would produce [X].
In this case, Ruby won't be able to look for Y in one of ancestors of X and will throw a NameError. Rails (or any other framework with autoloading) will try to load X::Y after that.
See this article for more information: https://blog.jetbrains.com/ruby/2017/03/why-you-should-not-use-a-class-as-a-namespace-in-rails-applications/
In Ruby 2.5:
Top level constant lookup removed.You may use nested classes without fear of encountering this bug.

In the addition to previous answers: Module in Ruby is a class
$ irb
> module Some end
=> nil
> Some.class
=> Module
> Module.superclass
=> Object

Related

How are modules and classes used differently in Ruby?

How is a module different from a class, and when should we use modules? Can we create instances of a module, or inherit from one?
Pragmatic Differences and Oversimplifications
Modules and classes share a lot of similarities in Ruby. The pragmatic difference is that modules are generally used to:
Provide namespacing to avoid classname collisions. For example, the following code would create a Bar class in two separate modules, addressable as Foo::Bar and Baz::Bar:
module Foo
class Bar; end
end
module Baz
class Bar; end
end
Enclose or wrap multiple classes in a single namespace. For example, to provide Foo::Bar and Foo::Baz:
module Foo
class Bar; end
class Baz; end
end
Provide mixins. Since Ruby only uses single inheritance, you #include modules within a class, or #extend objects with them. This allows you great flexibility in how you compose classes, as well as increasing reusability. For example, to provide instances of both Baz and Quux with a #bar method:
module Foo
def bar; end
end
class Baz
include Foo
end
class Quux
include Foo
end
There are certainly other differences, but in general you can think of modules as special types of classes. This is technically true because Module.class === Class, but don't get carried away with the oversimplification. It should, however, provide you with a pragmatic starting point.
There are a bunch of different questions here, and I agree with the others that this is something you really need to get from some basic Ruby programming sources. However, a potted set of answers to get you going:
How is a module different from a class,
A class is a thing that makes objects. Objects have both actions and state: that is, you can tell an instance of a class to do things (in methods), and it will store information about itself (in attributes).
In Ruby we use a module for a bunch of things, mostly:
to group classes together
to make functionality to add to classes (a mixin).
when we want a bunch of actions but don't need a class.
and when should we use modules?
You can't naturally use a module to create objects like a class, and it doesn't really hold state like a class. So if you want to have a bunch of objects that each have state and can do stuff, you need a class, not a module.
If don't need those things, you are probably looking at a module. But Ruby is a really accomodating language -- there is more than one way to do anything.
Can we create instances of a module, or inherit from one?
Nope. You need a class for that.
You want to characterize (i.e., give methods, variables, constants to) a set of objects by assuming relations between the set of objects and character assigners (i.e., classes/modules). In general, not just in computing, there are two modes (among others) of having such relation.
One mode is that the objects have one and only one character assigner chosen from a given group. Examples from other fields are:
radio button in GUI
major mode in emacs text editor
a person's name, parents, etc.
In Ruby's object oriented programming model, this is expressed as the set of object being an instance of a class. Every Ruby object is an instance of at least one class, and at most one class. It can be an instance of String class or Array class, but not both.
The other mode is that for each character assigner (possibly multiple), the objects either carries that character or not, and that is individually decided for each character assigner. Examples from other fields are:
check box in GUI
minor mode in emacs text editor
whether a person is an alumni of a school, an (ex-)employee of a company, etc.
In Ruby's object oriented programming model, this is expressed as the set of object inheriting a module. A Ruby object may or may not inherit Enumerable module, it may or may not inherit Comparable, and that is decided individually.

Is it unconventional to define a subclass within it's parent class?

Is it conventional to define a subclass under it's parent class like below?
class Element
class Div < Element
end
class Paragraph < Element
end
end
Or is it more appropriate to make a module to contain the subclasses?
class Element
end
module Elements
class Div < Element
end
class Paragraph < Element
end
end
Or to create a "base" class in a module and define the subclasses within the same module?
module Element
class Base
end
class Div < Base
end
class Paragraph < Base
end
end
Or is it better to force a naming convention?
class Element
end
class DivElement < Element
end
class ParagraphElement < Element
end
It seems every library chooses a different namespacing/naming convention.
Which is the best to use?
What are the pros and cons of each?
TL;DR: The most conventional and best way to do this is with a module containing a base class and its subclasses. But let's go over everything.
There aren't many official sources on this; however, it is the style to use modules to contain libraries, code, and groups of classes.
Subclasses in Superclass
Pros:
Self-contained: The entire class system is contained under one name
Cons:
Unnatural: Who would think to look inside a superclass for a subclass?
Having the subclasses in a superclass really depends on situation. However, any benefits of this method are also achieved by the module method. But in practice, this just isn't done. Classes are here to contain methods, instance variables, class methods, etc. But classes can be thought of as a last level of nesting -- you don't have a class in a class unless it's a very specific circumstance.
The one case where I can think of this making sense is a case where the only way subclasses are used is through the superclass, for example a Formatter class that has internal subclassses like XML, PDF, etc. Let's say that you only use these classes by doing things like Formatter.new(:xml). But if we're doing this, the subclasses should be private and not accessible to the outside world anyway. And at that point, inheritance is a very C++y way and not Rubyish at all.
Base class outside module, subclasses within
Pros:
I can't think of any
Cons:
Implies Non-conected: If Element is not in the same namespace as its children, what, beyond the name tells me that it's even related?
This method is very unnatural. It makes it look as if Element has nothing to do with it's children, or if looked at differently, that it's children are internal implementation details that aren't to be dealt with. Either way it looks like shabby, sloppy naming and bad code structure planning. If I were reading code using this, I'd have to look at the contents of the Elements module to see that Element was subclassed at all -- and this isn't the most natural thing to do.
Class and subclasses in module (best solution)
Pros:
Contained: The superclass and all the Element classes are contained in one namespace, allowing them to be easily imported, required, iterated, etc. Also assists metaprogramming.
Includable: The classes can be easily includeed into any code.
Clear: There is an obvious association between Element and the subclasses. They are obviously a bundle of functionality.
Cons:
Encourages lazy naming: This does encourage you to name classes things like Base that are very ambiguous.
This is the best approach. It makes the classes a neat bundle, while still showing an obvious association and an obvious "Here, use my Div class" (as opposed to the subclasses-in-class strategy). Also, this is really helpful for metaprogramming, where having everything in a module is crucial to make things work. Finally, this works well with constructs like autoload, require_relative, include, etc. Those show that this is the way the language was designed to be used.
Force a naming convention
Pros:
Simple: No complexity here.
Removes ambiguity: Removes ambiguity from short names like Div or Para by turning them into DivElement and ParaElement.
Cons:
Archaic: Naming conventions to group classes or methods should only exist in languages that don't have a better way to do it, like C or Objective-C. C++ dropped it as soon as it got namespaces.
No programatic grouping: These naming conventions, while clear to humans, make the class structure very cloudy to metaprograming code, and make it impossible for the program to deal with the classes as a group
Pollutes global namespace: This creates many, many names in the global namespace, which is always a bad idea.
This is a very, VERY bad solution. It encorages writing sloppy, C-style code with little organization and little sense. These kinds of naming conventions should only be used in languages where there is no better solution, and Ruby has plenty of better solutions. Even defining all the classes in an array is better than a naming convention.
Note: However, if you really want to, you can define a naming convention on short names like Div or Para as long as you still keep them in a module, so that it's Elements::DivElement. However, this violates DRY, and I wouldn't suggest it.
Conclusion
So, you really have two options. Just put everything in a module:
module Elements
class Element; end
class Div < Element; end
#etc...
end
Or, put everything in a module with a naming convention:
module Elements
class Element; end
class DivElement < Element; end
#etc...
end
I sugest the former for clarity, use of standard methods, and metaprogramming reasons.
This is a problem I have faced many times - you have some shared functionality and a few different implementation classes that use it - it's natural for the shared functionality and the namespace for the implementation classes to have the same name.
I have never had a problem defining a subclass under its parent class as in your first example - except for the fact that it has sometimes confused other developers on my team. So depending on who you are working with and what their preferences are I don't think there's any problem with this approach.
I would still prefer the second approach, with a different name for the namespace, if there was a name that made sense. If there isn't, I'd use the first approach.
I would avoid using names like Base, as in my opinion this sort of generic name encourages you to just throw any old stuff in there, whereas a name that describes what the class does will (hopefully) make you think each time you add a method if it really belongs there.
And I'm really not a fan of compound names as in your naming convention example, which I justify to myself with a sort of vague feeling that it's like database normalisation - each field (or class name) should contain only one piece of information.
Anyway, I hope this helps you. I can't really draw from any sources other than my own experience (it's for you to decide if you think that's 'credible'), as I do think there's no absolute answer to this question. It is in a large part subjective.
Name space and inheritance are for different purposes. Use name space to encapsule a module within another. Use inheritance to define a module using the methods/variables/constants of another as a default.
It could happen in principle that you may want a module to both be within the name space of and inherit from the same single module, but that depends on your use case. Without discussing over a particular use case, it cannot be decided which way among the ones you presented is the best.

Ruby modules and classes

I am just starting Ruby and learning the concept of modules. I understand that one use of modules is to better organize your code and avoid name clashes. Let's say I have bunch of modules like this (I haven't included the implementation as that's not important)
:
module Dropbox
class Base
def initialize(a_user)
end
end
class Event < Base
def newFile?
end
def newImage?
end
end
class Action < Base
def saveFile(params)
end
end
end
and another module:
module CustomURL
class Base
def initialize(a_user, a_url, a_method, some_args, a_regex)
end
end
class Event < Base
def initialize(a_user, a_url, a_method, some_args, a_regex)
end
def change?
end
end
class Action < Base
def send_request(params)
end
end
end
I am going to have a bunch of these modules (10+, for gmail, hotmail, etc...). What I am trying to figure out is, is this the right way to organize my code?
Basically, I am using module to represent a "service" and all services will have a common interface class (base for initializing, action for list of actions and event for monitoring).
You are defining families of related or dependent classes here. Your usage of modules as namespaces for these families is correct.
Also with this approach it would be easy to build abstract factory for your classes if they had compatible interface. But as far as I see this is not the case for current classes design: for example Dropbox::Event and CustomURL::Event have completely different public methods.
You can reevaluate design of your classes and see if it is possible for them to have uniform interface so that you can use polymorphism and extract something like BaseEvent and BaseAction so that all Events and Actions will derive from these base classes.
Update: As far as you define services, it might be useful to define top-level module like Service and put all your classes inside this module. It will improve modularity of your system. If in the future you would refactor out some base classes for your modules services, you can put them in the top-level namespace. Then your objects will have readable names like these:
Service::Dropbox::Event
Service::Dropbox::Action
Service::CustomURL::Event
Service::CustomURL::Action
Service::BaseEvent
Service::BaseAction
I have some similar code at work, only I'm modeling networking gear.
I took the approach of defining a generic class with the common attributes and methods, including a generic comparator, and then sub-class that for the various models of hardware. The sub-classes contain the unique attributes for that hardware, plus all the support code necessary to initialize or compare an instance of that equipment with another.
As soon as I see the need to write a method similar to another I wrote I think about how I can reuse that code by promoting it to the base-class. Often this involves changing how I am passing parameters, and instead of using formal parameters, I end up using a hash, then pulling what I need from it, keeping the method interface under control.
Because you would have a lot of sub-classes to a base class, it's important to take your time and think out how that base-class should work. As you add sub-classes the task of refactoring the base will get harder because you will have to change other sub-classes. I always find I go down some blind-alleys and have to back up a bit, but as the class matures that should happen less and less.
As you will notice soon, there is no 'right way' of organizing code.
There are subtle differences in readability that are mostly subjective. The way you are organizing classes is just fine for releasing your code as a gem. It usually isn't needed in code that won't be included in other peoples projects, but it won't hurt either.
Just ask yourself "does this make sense for someone reading my code who has no idea what my intention is?".

Ruby: nesting classes in classes same as nesting classes in modules?

In Ruby, one can declare classes like
class A
class B
end
end
and then instantiate the inner class like A::B.new.
Does B have some sort of special relationship with A (as is the case in Java) or is A just its namespace? In other words, is nesting a class in a class the same as nesting it in a module?
This is one of those times when you should really just fire up irb and try it.
Yes, a class can be defined within another class. Since a class's superclass is Module (i.e. Class extends Module), they can do almost everything a Module can. A notable exception is that you cannot include (mixin) a class.
That said, there's very little reason to actually use this design pattern. It is more likely that A and B can be considered siblings. There is no need to arbitrarily namespace until you are blue in the face. If you are more than 3 levels deep, stop and consider refactoring.
A better design pattern for this example might be:
module Alphabet
class A; end
class B; end
end
For something more complicated, this continues to work nicely using Mixins:
module Animals
class Dog
include Walking
end
module Walking
# some methods pertaining to the ability to walk
end
end
Yes, it's essentially the same as nesting in module. Nested class does not have any kind of special relationship to the class it's nested in.
Yes and...no. A Module can't be instantiated whereas a class can, so there is a difference in nesting a class within a Module vs. using a class nested within a class.
For example: You cannot instantiate an object of Ford here (i.e. Cobra, F-150, Mustang, etc.) because you cannot instantiate a module,.
`module Ford
class Engine
...
end
end`
But you can have an instance of the class Ford as well as instances of Ford engines with using nested classes like so:
`class Ford
class Engine
##actions = ['list', 'find', 'add', 'quit']
def self.actions; ##actions; end
end
def self.truck_exists?
#Some more stuff here
end
end`
Classes (and Modules) have different usages:
Namespace: when you define a class (or module) inside another class (or module), you have to use a different notation outside the defining class to reach the inner class or module.
Template for instances: There modules and classes behave totally (well mostly) different.
Inheritance: You may extend a class, so you inherit all its attributes and methods, which works for modules as well. Or you may include a module (not: a class) to add its methods (and attributes) to your scope. Ruby plays here tricks by mixin the module in the class hierarchy.
So in the context of using name spaces, they are the same. However I would all the time use modules (only), but that is more a matter of style. The best book on this topic is in my opinion "Metaprogramming Ruby" by Paolo Perrotta.

Which is the best/most used singleton coding convention in Ruby?

In the Ruby Standard Library we have the Singleton class:
http://ruby-doc.org/stdlib/libdoc/singleton/rdoc/index.html
We can make any class a singleton by including this class inside. I just rarely see this used. When would it make sense to use this Singleton class vs. just using plain old class methods - also known as singleton methods?
Said in another way: Which Singleton coding-convention are the best and why? Here are three ways I could think of:
require 'singleton'
class Foo
include Singleton
# method definitions go here...
end
Foo.instance.do_something!
Versus
class Foo
class << self
# method definitions go here...
end
end
Foo.do_something!
Versus
module Foo
class << self
# method definitions go here...
end
end
Foo.do_something!
WARNING: Opinions ahead!
If you just need a single object, just use a single object:
class << (Foo = Object.new)
# method definitions go here...
end
Foo.do_something!
Modules are for sharing behavior between objects. Classes are factories for objects. Note the plural: if you have only one object, you need neither a facility for sharing behavior nor a factory for producing multiple copies.
Whether or not this is considered idiomatic Ruby depends largely on which "Ruby" you are talking about: are you talking about Ruby as used by Rails programmers, Ruby as used by Smalltalk programmers, Ruby as used by Java programmers or Ruby as used by Ruby programmers? There are significant differences in the styles used by these different communities.
For example, old time Rubyists like David Alan Black tend to start always with just objects and singleton methods. Only if they later on discover duplicated behavior between objects will they extract that behavior into a mixin and extend the objects with it. (Note that at this stage, there still aren't any classes!)
Classes are created, again, only by refactoring, not by upfront design, when and only when there is duplicated structure between objects.
The most common approach I've seen is neither a singleton nor a class that you never instantiate. The most common and idiomatic way to do this is a module.

Resources