Ruby Best Practices: Working with Classes

See the example below, I believe it is better to use the second method, but the first also works. Which method is best suited and what are its matches?

class Test def start p "started" end test = Test.new test.start end class Test2 def start p "started" end end test2 = Test2.new test2.start 
+4
source share
4 answers

You can do this in several ways, it is up to you. That is fun ...

 class Test def start p "started" end new end.start 

More seriously, your first example encapsulates everything in one class. This is normal for a script; it puts everything in your own namespace and basically avoids the mysterious main context of the object. You can define nested classes if you need them.

However, the second approach is more conditional.

+2
source

I would say that the second option makes sense. The first will not lead to an error, but the instance of the object is completely outdated and pointless. External variables are not visible within the class:

 var = "string" class A var = A.new end puts var #=> string 

There is no closure, the outer var is different from the outer in the class. This means that your object is “lost” after creation and will no longer be accessible, and will ultimately obey the GC.

When you say that the first example “works,” working in this context means that you can call a method on a newly created object immediately after creating this object in the class area. But it is impossible to save this object as a reference for later use (without assigning class (instance) variables to it).

If you don’t need a link for later use, and you really want to perform such a “single snapshot” operation, it would be more idiomatic to use a class method that can be called without creating an instance of the object or to perform the necessary actions in initialize if it what needs to be done with each instance.

+4
source

Defining a class that creates an object of itself at boot time is not a good idea. The object will be available only for it, and not for its parent area (of course, you can still access it through ObjectSpace::each_object ).

+3
source

Some recommendations for Ruby classes

  • Use a consistent structure in class definitions.
  • Do not insert multi-line classes inside classes. Try to have such nested classes each in your own file in a folder named as containing the class.
  • Prefer modules for classes only using class methods. Classes should only be used when it makes sense to instantiate them.
  • Thank you for using function_module over the self extension if you want to turn module instance methods into class methods.
  • When developing a class hierarchy, ensure that they comply with the Liskov Substitution Principle.
  • Try to make your classes as SOLID as possible.
  • Always provide the correct to_s method for classes representing domain objects.
  • Use the attr family of functions to define trivial accessories or mutators.
  • Avoid using attr . Use attr_reader and attr_accessor .
  • Consider using Struct.new , which defines trivial accessors, constructors, and comparison operators for you.
  • Do not expand the instance initialized by Struct.new . Extending it introduces a redundant class level and can also introduce strange errors if the file is required several times.
  • Consider adding factory methods to provide additional reasonable ways to instantiate a particular class.
  • Prefer duck seal by inheritance.
  • Avoid using class variables (@@) because of their "nasty" behavior in inheritance.
  • Assign the correct levels of visibility to methods (private, protected) in accordance with their intended use. Do not leave, leaving everything publicly available (which is the default). In the end, we are now coding for Ruby, not Python.
  • Reject the public , protected and private methods as well as the definitions of the methods to which they apply. Leave one blank line above the visibility modifier and one blank line below to emphasize that it applies to all methods below.
  • Use def self.method to define class methods. This simplifies code refactoring because the class name is not duplicated.

This is the best document for best practices at ruby: https://github.com/bbatsov/ruby-style-guide

+2
source

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


All Articles