difference between modules inside a class and class inside a modules in ruby - ruby

I think both are used for namespace.
Modules are generally mixed into classes, right? So, what would be the purpose of defining a module inside a class?

Generally speaking modules have two uses:
Namespacing modules. When you nest stuff here and the module is intended only for specifying paths.
Functional modules. When the module has actual functionality that is intended to be called directly on the module or the module is intended to be included/extended.
Classes should be used for functionality only, even though Ruby doesn't enforce it.
Trying to do something but the above (like use module for both namespacing and functionality (1) or use a class for namespacing (2)) will generally confuse you.
(1) Some will disagree pointing to the rails' module with instance methods that also holds another module, called ClassMethods. I think it would have been cleaner if there was a module with two modules - ClassMethods and InstanceMethods instead.
(2) Some will disagree. A probably valid case is if you try to emulate private classes from other languages (where the private class will be nested inside your public class).

Related

In Ruby can I have a method that can be used in any class within a specific module

I have a logger method that I would like to make accessible to all classes within a module. Is there a way of doing that without just putting the method in a module and including it in every single class? I'd also prefer not to have to call the method with the module (e.g. Module.logger)
From what I can tell, the class does not inherit at all from the module it is in, so I can't figure out anyway of doing this, but I thought I'd ask to be sure.
Ruby doesn't have nested classes. The classes aren't in the module. There is no relationship whatsoever between the classes and the module.
The constants which reference the classes are namespaced inside the module, but that has nothing to do with the relationship between the classes and the module.
So, no, what you want is not possible, for the simple reason that there is no relationship between the classes and the module that could be exploited to somehow make the method available. You will have to go for good old (mixin) inheritance.

Why do the class variables(##foo) act such way in Ruby inheritance?

I am Intern Ruby on Rails Developer, who is willing to understand guts of core Ruby library and it's dependecies.
Traversing through it I came across a strange fact - in all the guides it was recommended not to use class variables in Ruby classes beacause of them being shared in all the inheritance chain below of class where we use such variable ##foo or whatever we call it and even classes where we me mixin the modules where we declared such class variables.
What is a purpose of such global scope of class variables visibility? Why it is not fixed to more safe behavior in one of the Ruby relases if community now considers a malicious practice to use class variables at all?

What criteria justifies using a Module over a Class in Ruby?

I'm reading my ruby book. Looking at the code below,
module Destroy
def destroy(anyObject)
#anyObject = anyObject
puts "I will destroy the object: #{anyObject}"
end
end
class User
include Destroy
attr_accessor :name, :email
def initialize(name,email)
#name = name
#email = email
end
end
my_info = User.new("Bob","Bob#example.com")
puts "So your name is: #{my_info.name} and you have email #{my_info.email}"
user = User.new("john","john#example.com")
user.destroy("blah")
I could've just created another method inside my class. Why would I want to do this? Why would I want to use a module? It's not like embedding this into other classes is any easier than just using normal inheritance.
You can think of a module and the methods and constants inside of it as more of providing utility functions and actions that you can include to other objects as you see fit. For example, if you wanted to use destroy function in the objects Foo and Bar you would do similarly:
class Foo
include Destroy
# other code below
end
class Bar
include Destroy
# other code below
end
Now any Foo or Bar object has access to all the methods or constants inside of destroy.
Modules define a namespace, a sandbox in which your methods and constants can play without having to worry about being stepped on by other methods and constants. The ruby docs goes into more depth about this and includes a good example practical of when you would want to use it as seen below:
module Debug
def whoAmI?
"#{self.type.name} (\##{self.id}): #{self.to_s}"
end
end
class Phonograph
include Debug
# ...
end
class EightTrack
include Debug
# ...
end
ph = Phonograph.new("West End Blues")
et = EightTrack.new("Surrealistic Pillow")
ph.whoAmI? » "Phonograph (#537766170): West End Blues"
et.whoAmI? » "EightTrack (#537765860): Surrealistic Pillow"
In this example, every class that includes Debug has access to the method whoAmI? and other methods and constants that Debug includes without having to redefine it for every class.
Some programming languages such as C++, Perl, and Python allow one class to inherit from multiple other classes; that is called multiple inheritance. Ruby does not support multiple inheritance. That means each class can only inherit from one other class. However, there are cases where a class would benefit by acquiring methods defined within multiple other classes. That is made possible by using a construct called module.
A module is somewhat similar to a class, except it does not support inheritance, nor instantiating. It is mostly used as a container for storing multiple methods. One way to use a module is to employ an include or extend statement within a class. That way, the class gains access to all methods and objects defined within the module. It is said that the module is mixed in the class. So, a mixin is just a module included in a class. A single module can be mixed in multiple classes, and a single class can mix in multiple modules; thus, any limitations imposed by Ruby's single inheritance model are eliminated by the mixin feature.
Modules can also be used for namespacing. That is explained in this post at the Practicing Ruby website.
You are writing a module in the same file as the class, but not necessarily inside the class, but anyway.
For me there are 3 reasons to use a module(more details here):
Modules provide a namespace and prevent name clashes.
Modules implement the mixin facility.
When you have a very complex and dense class, you can split it into
modules and include them into the main class.
Your example is fairly simple, it would indeed make more sense to write the method in the class itself, but try to imagine a complex scenario.

Are modules == mixins in ruby?

I have read in many textbooks that
In Ruby,a class can only be a subclass of one class. Mixins, however, allow classes without a common ancestor to share methods.
In practice, whenever I need to implement multiple inheritance. I have use Modules & not mixins. for example:
Module name_goes_here
def method_name_goes_here
.....
end
end
Then, I just include them in a class
class MySubClass < MySuperClass
include module_name
end
now, I have referred to multiple ruby books each talking about mixins & then suddenly, all of they start talking about modules without making it clear what is the relation of mixins & modules.
so, Question is:
Are modules == mixins in ruby? if yes, then why. if no, then what's the difference?
PS: sorry, if its a silly question
Mixins are a language concept that allows to inject some code into a class.
This is implemented in Ruby by the keyword include that takes a Module as a parameter.
So yes, in Ruby, mixins are implemented with modules. But modules have other uses than mixins.
For example, modules can also be used for namespacing your classes or encapsulating utility functions to keep from polluting the global namespace.
From wikipedia article
In object-oriented programming languages, a mixin is a class that provides a certain functionality to be inherited or just reused by a subclass, while not meant for instantiation (the generation of objects of that class).
So yes, modules in Ruby provide a way to reuse functionality without instantiating modules themselves. I'd say, "mixins in ruby are implemented with modules", but not "mixins are modules and vice versa".

When a module is imported into a Ruby class, is it similar to composition?

When you import a module into a class, is it similar in nature to OOP composition?
No, it's more like multiple inheritance, but not completely the same. Modules can be used to mix-in functionality, so you don't have to rewrite the same code for multiple classes. Composition is where objects hold references to other objects.
I may be getting my design pattern terminology mixed up, but have you looked at def_delegator and def_delegators from Ruby's standard library forwardable?

Resources