Using the vs Module class to package code in Ruby

Say I have a bunch of related functions that don't have a constant state, say, various operations in a difference string package. I can either define them in a class or module (using self ), and they can be accessed in exactly the same way:

 class Diff def self.diff ... def self.patch ... end 

or

 module Diff def self.diff ... def self.patch ... end 

Then I can do Diff.patch(...) . What is โ€œbetterโ€ (or โ€œrightโ€)?

The main reason I need to group them is namespace problems, common function names are used elsewhere.

Edit: Changed the example from the matrix to diff. The matrix is โ€‹โ€‹a terrible example, because it has a state, and everyone began to explain why it is better to write them as methods, and not answer the actual question. :(

+2
source share
5 answers

In your two examples, you are not actually defining methods in a Class or Module ; you define singleton methods for an object that is Class or Module , but can be almost any object. Here is an example with String :

 Diff = "Use me to access really cool methods" def Diff.patch # ... end 

You can do any of these, and this will work, but the best way to group related methods in Module like normal instance methods (i.e. without self. ):

 module Diff extend self # This makes the instance methods available to the Diff module itself def diff ... # no self. def patch ... end 

Now you can:

  • use this functionality from any class (with include Diff ) or from any object (using extend Diff )
  • an example of this use is the extend self line, which allows Diff.patch to be called.
  • even use these methods in the global namespace

For example, in irb :

 class Foo include Diff end Foo.new.patch # => calls the patch method Diff.patch # => also calls Diff.patch include Diff # => now you can call methods directly: patch # => also calls the patch method 

Note: extend self will "modify" the Diff module object itself, but it will not affect module inclusion. The same thing happens for def self.foo , foo will not be accessible to any class, including it. In short, only instances of the Diff method are imported using include (or extend ), not single methods. Only subclassing the class will ensure the inheritance of both the instance method and the singleton method.

If you really want to include a module to provide both instance methods and singleton methods, this is not entirely easy. You should use self.included hook:

 module Foo def some_instance_method; end module ClassMethods def some_singleton_method; end end def self.included(base) base.send :extend, ClassMethods end def self.will_not_be_included_in_any_way; end end class Bar include Foo end # Bar has now instance methods: Bar.new.some_instance_method # => nil # and singleton methods: Bar.some_singleton_method # => nil 
+3
source

The main difference between modules and classes is that you cannot instantiate a module; you cannot do obj = MyModule.new . Suppose you do not want to create any instances, so I recommend using only the module.

However, you should reconsider your approach: instead of using arrays of arrays or what you do to represent the matrix, it would be more elegant to make your own class to represent the matrix or find a good class that someone else wrote .

+3
source

Ruby modules are used to indicate behavior, part of related functions.

Ruby Classes are used to indicate both state and behavior of a particular entity.

There is a principle in software development that says code is a commitment, so use less code. In the case of Ruby, the difference in the lines of code is cero. Thus, you can use any method (if you do not need to save state)

If you want to be a purist, then use the module, since you will not use the state function. But I would not say that using the class is wrong.

As information on the little things: in Ruby, a class is a kind of module.

http://www.ruby-doc.org/core-1.9.3/Class.html

+2
source

Also works

 Matrix = Object.new def Matrix.add ... def Matrix.equals ... 

This is because the so-called "class methods" are simply methods added to a single object, and it does not really matter what the class of the object is.

+1
source

As a form, the module is more correct. You can still instantiate the class, even if it has only class methods. You can think of a module here as a static C # or Java class. Classes also always have instance-related methods ( new , allocate , etc.). Use the module. Class methods usually have something to do with objects (creating them, manipulating them). A.

+1
source

Source: https://habr.com/ru/post/956670/


All Articles