The Style Guide for writing classes and modules in Ruby and the style guide for writing ruby

Source: Internet
Author: User

The Style Guide for writing classes and modules in Ruby and the style guide for writing ruby

Use a consistent structure in the class definition.

class Person   # extend and include go first   extend SomeModule   include AnotherModule   # constants are next   SOME_CONSTANT = 20   # afterwards we have attribute macros   attr_reader :name   # followed by other macros (if any)   validates :name   # public class methods are next in line   def self.some_method   end   # followed by public instance methods   def some_method   end   # protected and private methods are grouped near the end   protected   def some_protected_method   end   private   def some_private_method   end  end

A class tends to use modules instead of class methods. The category should be used only when the instance is created properly.

 # 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  end

When you want to change the module's instance method to the class method, you prefer to use module_function over extend self.

 

  # bad  module Utilities   extend self   def parse_something(string)    # do stuff here   end   def other_utility_method(number, string)    # do some more stuff   end  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  end

When designing class hierarchies make sure that they conform to
Liskov Substitution Principle.

Ensure that they comply with the Liskov Substitution Principle principles at the design level. (Note: If a function references an instance of the parent class, it must be replaced by an instance of its subclass, and the basic functions of the function remain unchanged. (although the function can be extended ))

Liskov replacement principle: Subtypes must be able to replace their base types <br/>
1. if every o1 object of Type T1 has object o2 of Type T2, so that all program P defined by T1 can be replaced by o2 in all object o1, if the behavior of program P does not change, Type T2 is the child type of Type T1. <Br/>
2. In other words, if a software entity uses a base class, it must be applicable to its subclass, and it cannot detect the differences between the base class object and the subclass object. Only when the feature class replaces the base class and the function of the software entity does not change can the base class be reused. <Br/>
3. Barbar Liskov (Barbara RYS) proposed the principle of Lishi replacement, which is the cornerstone of inheritance reuse. <Br/>
4. Whether an inheritance complies with the Li's replacement principle can determine whether the inheritance is reasonable (whether there are hidden defects ).

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

The to_s method is always provided for your own class to represent the objects contained in 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  end

Use attr function members to define the accessors or modifier methods for each instance variable.

 # 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  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  end

Avoid using attr. Use attr_reader and attr_accessor as alternatives.

  # 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 (constructor) 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  end  # better  class Person < Struct.new(:first_name, :last_name)  end

Consider using Struct. new, which defines the trivial accessors, constructor, and 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  end  # better  Person = Struct.new(:first_name, :last_name) do  end

Do not extend a Struct. new-it is already a new class. Extension will generate a redundant class level
In addition, it may cause a weird error if the file is loaded multiple times.

Consider adding factory methods to provide flexible methods for creating specific class instances.

class Person   def self.create(potions_hash)    # body omitted   end  end

The duck type (duck-typing) is better than the inheritance type.

 # bad  class Animal   # abstract method   def speak   end  end  # extend superclass  class Duck < Animal   def speak    puts 'Quack! Quack'   end  end  # extend superclass  class Dog < Animal   def speak    puts 'Bau! Bau!'   end  end  # good  class Duck   def speak    puts 'Quack! Quack'   end  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 (class variables of the parent class can also be modified in the subclass ).

 class Parent   @@class_var = 'parent'   def self.print_class_var    puts @@class_var   end  end  class Child < Parent   @@class_var = 'child'  end  Parent.print_class_var # => will print "child"

As shown in the preceding example, all subclasses share class variables and can directly modify class variables. It is better to use class instance variables.

Assign appropriate visibility (private, protected) to methods based on their purpose, and do not make all methods public (this is the default setting ). This is Ruby, not Python.

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

 class SomeClass   def public_method    # ...   end   private   def private_method    # ...   end   def another_private_method    # ...   end  end

Def self. method is used to define the singleton method. When the code is restructured, this makes the code easier because the class names are not repeated.

  class TestClass   # bad   def TestClass.some_method    # body omitted   end   # good   def self.some_other_method    # body omitted   end   # Also possible and convenient when you   # have to define many singleton methods.   class << self    def first_method     # body omitted    end    def second_method_etc     # body omitted    end   end  end  class SingletonTest   def size    25   end  end  test1 = SingletonTest.new  test2 = SingletonTest.new  def test2.size   10  end  test1.size # => 25  test2.size # => 10

In this example, test1 and test2 are different in the same type, but test2 has a new size method, so the rows of the two are different. The singleton method is the singleton method ).

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.