Style guide for writing classes and modules in Ruby _ruby topics

Source: Internet
Author: User
Tags class definition instance method

Use a consistent structure in the class definition.

Class Person
   # Extend and include the Go
   extend Somemodule
   include Anothermodule

   # constants are 5/>some_constant =

   # Afterwards we have attribute macros
   Attr_reader:name # followed by the other

   macros (if a NY)
   Validates:name

   # public class methods are next with line
   def self.some_method
   end

   # followed B Y Public instance Methods
   def Some_method end
   # Protected and private methods the are grouped near the

   end
   
    protected

   def some_protected_method
   end

   private

   def some_private_method
  End


   

Prefer to use module, rather than classes with only class methods. Categories should be used only when creating instances that are reasonable.

 # Bad
  class SomeClass
   def self.some_method
    # body omitted
   end

   def self.some_other_method
   End
  End

  # good
  module SomeClass
   module_function

   def some_method
    # body omitted
   end

   def some_other_method
   End
  

When you want to turn the instance method of a module into a class method, the preference for using module_function is better than extend self.

  # bad
  module Utilities
   extend self

   def parse_something (string) # does stuff here-end

   def Other_utility_method (number, String)
    # do some the stuff
   end

  # good
  module Utilities
   module_function

   def parse_something (string) # do stuff-here-end

   def other_utility_method ( Number, String)
    # do some more stuff
   end
  

When designing class hierarchies make sure this they conform to the
Liskov substitution principle.

Ensure that they conform to the Liskov substitution principle principles when designing class levels. (Translator Note: The LSP principle probably means: if an instance of the parent class is referenced in a function, it must be replaced with an instance of its subclass, and the basic function of the function will not change.) (Although functionality is allowed to be extended))

Liskov substitution principle: subtypes must be able to replace their base types <br/>
1. If each type is a T1 object O1, there is a type of T2 object O2, so that all program P defined by T1 when all the object O1 are substituted for O2, the behavior of program P is not changed, then the type T2 is the subtype of type T1. <br/>
2. In other words, if a software entity uses a base class, it must apply to its subclasses, and it cannot detect the difference between the base class object and the subclass object at all. The base class can be truly reused only if the derived class replaces the base class while the functionality of the software entity has not changed. <br/>
3. The principle of the Richter substitution, proposed by Barbar Liskov (Barbara Richter), is the cornerstone of succession reuse. <br/>
4. Whether an inheritance conforms to the principle of the Richter substitution, it is possible to determine whether the inheritance is reasonable (whether it is hidden or flawed).

Try to make your class as robust as possible [SOLID] (http://en.wikipedia.org/wiki/solid_object-oriented_design\). (

Always provide a to_s method for your own class to represent objects contained by this class (instance) object.

 Class Person
   attr_reader:first_name,: last_name

   def initialize (first_name, last_name)
    @first_name = first_name
    @last_name = last_name
   end

   def to_s
    ' # @first_name # @last_name
  End

Use the attr feature member to define accessors or modifier methods for individual instance variables.

 # bad
  class person
   def initialize (first_name, last_name)
    @first_name = first_name
    @last_name = last_ Name
   end

   def first_name
    @first_name
   end

   def last_name
    @last_name
  End

  # Good
  class person
   attr_reader:first_name,: last_name

   def initialize (first_name, last_name)
    @first_name = first_name
    @last_name = last_name
   End
  

Avoid using attr. Use Attr_reader and attr_accessor as substitutes.

  # bad-creates A single attribute accessor (deprecated in 1.9)
  attr:something, True
  Attr:one,: Two,: three # behaves as Attr_reader

  # good
  attr_accessor:something
  Attr_reader:one, two,: three

Consider using struct.new, which can define some trivial accessors,
Constructor (constructors) and comparison (comparison) operations.

  # Good
  class person
   attr_reader:first_name,: last_name

   def initialize (first_name, last_name)
    @first _name = first_name
    @last_name = last_name
   end

  # better
  class Person < Struct.new (: First_ Name,: last_name) End
  

Consider using Struct.new, which defines the trivial accessors (accessors), constructors (constructor), and comparison operators (comparison operators) for you.

  # Good
  class person
   attr_accessor:first_name,: last_name

   def initialize (first_name, last_name)
    @first_name = first_name
    @last_name = last_name
   end

  # better person
  = struct.new (: first_ Name,: last_name) do end
  

Don't go extend a struct.new-it's already a new class. Extending it creates an extra class hierarchy
And it could make a weird mistake if the file was loaded multiple times.

Consider adding a factory method to provide a flexible way to create a specific class instance.

Class Person
   def self.create (Potions_hash)
    # body omitted
   end
  

Duck type (duck-typing) is superior to inheritance.

 # Bad
  class Animal
   # abstract method
   def speak
   end

  # Extend Superclass
  class Duck & Lt Animal
   def speak
    puts ' quack! Quack '
   end

  # Extend Superclass
  class Dog < Animal
   def speak
    puts ' bau! bau! '
   End

  # Good
  class Duck
   def speak
    puts ' quack! Quack '
   end

  class Dog
   def speak
    puts ' bau! bau! '
   End End
  

Avoid the usage of class (@@) variables due to their "nasty" behavior
In inheritance.

Avoid using class variables (@@) because of their annoying inheritance habits (you can also modify the class variables of the parent class in subclasses).

 Class Parent
   @ @class_var = ' Parent '

   def Self.print_class_var
    puts @ @class_var
   end

  class Child < Parent
   @ @class_var = ' child '
  end

  Parent.print_class_var # => 'll print ' child '

As the example above sees, all subclasses share class variables, and you can modify class variables directly, and it's a better idea to use class instance variables at this point.

Assign them the right visibility (private, protected) based on the purpose of the method, and do not let all methods be public (this is the default setting). This is Ruby, not Python.

Public, protected, and private visibility keywords should have the same indentation as their (specified) methods. And leave a space between the different visibility keys.

 Class SomeClass
   def public_method
    #
   ... End

   Private

   def private_method
    #
   ... End

   def another_private_method
    #
   ... End End
  

Use Def Self.method to define a single instance method. This makes the code easier because the class name is not duplicated when the code is refactored.

  Class TestClass
   # bad
   def testclass.some_method
    # body omitted
   end

   # good
   def self.some_other _method
    # Body omitted
   end

   # Also possible and convenient the have to define many
   S.
   Class << self
    def first_method
     # body omitted
    end

    def second_method_etc
     # body omitted< C17/>end End-

  class singletontest
   def size
    end

  test1 = Singletontest.new
  test2 = singletontest.new
  def test2.size
   ten
  end
  Test1.size # => 25
  Test2.size # => 10

In this case, test1 and test2 belong to the same category, but test2 have a redefined size method, so the behavior of the two is different. The method of giving only one object is called a single instance method (singleton methods).

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.