Recommended syntax style in Ruby programming, and ruby programming syntax Style

Source: Internet
Author: User

Recommended style of grammar usage in Ruby programming, grammar style of ruby programming

Use :: to reference constants (including classes and modules) and constructors (such as Array () or Nokogiri :: HTML ()).
    Never use :: to call methods.

  # bad
  SomeClass :: some_method
  some_object :: some_method

  # good
  SomeClass.some_method
  some_object.some_method
  SomeModule :: SomeClass :: SOME_CONST
  SomeModule :: SomeClass ()

    Use brackets to enclose def parameters. Ignore parentheses when the method does not receive any parameters.

     

# bad
   def some_method ()
    # body omitted
   end

   # good
   def some_method
    # body omitted
   end

   # bad
   def some_method_with_arguments arg1, arg2
    # body omitted
   end

   # good
   def some_method_with_arguments (arg1, arg2)
    # body omitted
   end

    Never use for unless you know the exact reason for using it. Most of the time iterators can be used instead of for. for is implemented by a set of each (so you are indirectly adding a level), but there is a clue-for does not contain a new scope (unlike each) and the variables defined in its block are also outside Accessible.

 

  arr = [1, 2, 3]

  # bad
  for elem in arr do
   puts elem
  end

  # note that elem is accessible outside of the for loop
  elem # => 3

  # good
  arr.each {| elem | puts elem}

  # elem is not accessible outside each's block
  elem # => NameError: undefined local variable or method `elem '

    Never use then in multi-line if / unless.

    

# bad
  if some_condition then
   # body omitted
  end

  # good
  if some_condition
   # body omitted
  end

    If / unless on multiple lines always put the condition on the same line as if / unless.

 

  # bad
  if
   some_condition
   do_something
   do_something_else
  end

  # good
  if some_condition
   do_something
   do_something_else
  end

    I like ternary operations (? :) over if / then / else / end structures.
    It is more common and obviously more concise.

  # bad
  result = if some_condition then something else something_else end

  # good
  result = some_condition? something: something_else

    Use one expression to use only one expression under each branch of the ternary operation. This means that ternary operators should not be nested. It is better to use if / else in such situations.

  # bad
  some_condition? (nested_condition? nested_something: nested_something_else): something_else

  # good
  if some_condition
   nested_condition? nested_something: nested_something_else
  else
   something_else
  end

    Don't use if x: ...-it was removed in Ruby 1.9. Use ternary operation arithmetic instead.

  # bad
  result = if some_condition then something else something_else end

  # good
  result = some_condition? something: something_else

    Don't use if x; .... Use ternary operations instead.

    With the fact that if and case are expressions, they return a result.

  # bad
  if condition
   result = x
  else
   result = y
  end

  # good
  result =
   if condition
    x
   else
    y
   end

    Use when x then ... in one-line cases. The alternative syntax when x: xxx has been removed in Ruby 1.9.

    Don't use when x; .... See the rules above.

    Use! Instead of not.

    

# Bad-Because operators have precedence, parentheses are required.
  x = (not something)

  # good
  x =! something

  Avoid using !!.

  # bad
  x = 'test'
  # obscure nil check
  if !! x
   # body omitted
  end

  x = false
  # double negation is useless on booleans
  !! x # => false

  # good
  x = 'test'
  unless x.nil?
   # body omitted
  end

    The and and or keywords are banned. It's just not worth
    it. Always use && and || instead.

    The keywords and and or are prohibited. Its name is not true. Always use && and || instead.

   

 # bad
  # boolean expression
  if some_condition and some_other_condition
   do_something
  end

  # control flow
  document.saved? or document.save!

  # good
  # boolean expression
  if some_condition && some_other_condition
   do_something
  end

  # control flow

    document.saved? || document.save!

    Avoid multi-line?: (Ternary operator); use if / unless instead.

    Single-line subjects like to use if / unless modifiers. Another good way is to use && / || to control the process.

    

# bad
  if some_condition
   do_something
  end

  # good
  do_something if some_condition

  # another good option
  some_condition && do_something

    Boolean expressions use && / ||, and / or to control the flow. (Experience Rule: If you must use extra parentheses (expression logic), then you are using the wrong operator.)

   

 # boolean expression
  if some_condition && some_other_condition
   do_something
  end

  # control flow
  document.save? or document.save!

    Avoid multiple lines ?: (ternary operations), use if / unless instead.

    I like to use the if / unless modifier in single-line statements. Another good option is to use and / or for process control.

   

 # bad
  if some_condition
   do_something
  end

  # good
  do_something if some_condition

  # another good option
  some_condition and do_something

    Never use unless and else combinations. Rewrite them into positive conditions.

    

# bad
  unless success?
   puts 'failure'
  else
   puts 'success'
  end

  # good
  if success?
   puts 'success'
  else
   puts 'failure'
  end

    Don't use brackets to include if / unless / while conditions.

 

  # bad
  if (x> 10)
   # body omitted
  end

  # good
  if x> 10
   # body omitted
  end

    Do not use while / until condition do in multi-line while / until.

   

 # bad
  while x> 5 do
   # body omitted
  end

  until x> 5 do
   # body omitted
  end

  # good
  while x> 5
   # body omitted
  end

  until x> 5
   # body omitted
  end

    When you have a single line body, try using the while / until modifier.

  # bad
  while some_condition
   do_something
  end

  # good
  do_something while some_condition

    Negative condition judgments try to use until instead of while.

  

 # bad
  do_something while! some_condition

  # good
  do_something until some_condition

    Post-loop conditional judgments use Kernel # loop and break instead of begin / end / until or begin / end / while.

  

 # bad
  begin
   puts val
   val + = 1
  end while val <0

  # good
  loop do
   puts val
   val + = 1
   break unless val <0
  end

    Ignore parentheses around internal DSL method parameters (eg Rake, Rails, RSpec)
"Keyword" status methods (such as: attr_reader, puts) and property access methods. All other method calls use parentheses around the parameters.

    

class Person
   attr_reader: name,: age

   # omitted
  end

  temperance = Person.new ('Temperance', 30)
  temperance.name

  puts temperance.age

  x = Math.sin (y)
  array.delete (e)

  bowling.score.should == 0

    Ignore braces outside the implicit option hash.

  

 # bad
  user.set ({name: 'John', age: 45, permissions: {read: true}})

  # good
  user.set (name: 'John', age: 45, permissions: {read: true})

    Outer brackets and braces for internal DSL methods.

  class Person <ActiveRecord :: Base
   # bad
   validates (: name, {presence: true, length: {within: 1..10}})

   # good
   validates: name, presence: true, length: {within: 1..10}
  end

    Method calls do not require parameters, so parentheses are ignored.

 

  # bad
  Kernel.exit! ()
  2.even? ()
  fork ()
  'test'.upcase ()

  # good
  Kernel.exit!
  2.even?
  fork
  'test'.upcase

    I prefer to use {...} instead of do ... end in a single line of code. Avoid using {...} in multi-line code blocks (multi-line chaining usually becomes very ugly). Usually do ... end is used for flow control and method definition (for example in Rakefiles and some DSLs). Avoid using do ... end in chained calls.

  names = ['Bozhidar', 'Steve', 'Sarah']

  # bad
  names.each do | name |
   puts name
  end

  # good
  names.each {| name | puts name}

  # bad
  names.select do | name |
   name.start_with? ('S')
  end.map {| name | name.upcase}

  # good
  names.select {| name | name.start_with? ('S')} .map {| name | name.upcase}

    Some people will argue that multi-line chaining looks the same as using {...}, but they ask themselves-such code is really readable and why the contents of the code block cannot be extracted into beautiful methods .

    Consider using explicit block argument to avoid writing block
    literal that just passes its arguments to another block. Beware of
    the performance impact, though, as the block gets converted to a
    Proc.
    Consider using explicit block parameters to avoid writing block literals that only pass parameters to another block. Be careful of performance impact, even if,
    The block is converted to Proc.

  require 'tempfile'

  # bad
  def with_tmp_dir
   Dir.mktmpdir do | tmp_dir |
    Dir.chdir (tmp_dir) {| dir | yield dir} # block just passes arguments
   end
  end

  # good
  def with_tmp_dir (& block)
   Dir.mktmpdir do | tmp_dir |
    Dir.chdir (tmp_dir, & block)
   end
  end

  with_tmp_dir do | dir |
   puts "dir is accessible as parameter and pwd is set: # {dir}"
  end

    Avoid using return when flow control is not required.

 

  # bad
  def some_method (some_arr)
   return some_arr.size
  end

  # good
  def some_method (some_arr)
   some_arr.size
  end

    Avoid using self where it is not needed (It is only required when calling a self write accessor.)

    

# bad
  def ready?
   if self.last_reviewed_at> self.last_updated_at
    self.worker.update (self.content, self.options)
    self.status =: in_progress
   end
   self.status ==: verified
  end

  # good
  def ready?
   if last_reviewed_at> last_updated_at
    worker.update (content, options)
    self.status =: in_progress
   end
   status ==: verified
  end

    As a corollary, avoid placing methods (parameters) in the shadow of local variables unless they are equal.

    

class Foo
   attr_accessor: options

   # ok
   def initialize (options)
    self.options = options
    # both options and self.options are equivalent here
   end

   # bad
   def do_something (options = ())
    unless options [: when] ==: later
     output (self.options [: message])
    end
   end

   # good
   def do_something (params = ())
    unless params [: when] ==: later
     output (options [: message])
    end
   end
  end

    Do not use the return value of = (assignment) in a conditional expression unless the conditional expression is assigned in parentheses.
    This is a fairly popular ruby dialect, sometimes called a safe assignment in condition.

  

 # bad (+ a warning)
  if v = array.grep (/ foo /)
   do_something (v)
   ...
  end

  # good (MRI would still complain, but RuboCop won't)
  if (v = array.grep (/ foo /))
   do_something (v)
   ...
  end

  # good
  v = array.grep (/ foo /)
  if v
   do_something (v)
   ...
  end

    Use the shortcut self assignment operator wherever possible.

   

 # bad
  x = x + y
  x = x * y
  x = x ** y
  x = x / y
  x = x || y
  x = x && y

  # good
  x + = y
  x * = y
  x ** = y
  x / = y
  x || = y
  x && = y

    Use || = to initialize variables only when they are not initialized.

  # set name to Vozhidar, only if it's nil or false
  name || = 'Bozhidar'

    Do not use || = to initialize Boolean variables. (Think about what happens if the current value is false.)

  # bad-would set enabled to true even if it was false
  enable || = true

  # good
  enabled = true if enabled.nil?

    Use && = to preprocess variables that are not sure if they exist. Use && = only when (variable) exists
    Only change the value, remove the use of if to check its existence.

  # bad
  if something
   something = something.downcase
  end

  # bad
  something = something? nil: something.downcase

  # ok
  something = something.downcase if something

  # good
  something = something && something.downcase

  # better
  something && = something.downcase

    Avoid the use of the equality === operator. As the name suggests, this is an implicit use of case expressions and use outside of a case statement can produce unintelligible code.

   

 # bad
  Array === something
  (1..100) === 7
  / something / === some_string

  # good
  something.is_a? (Array)
  (1..100) .include? (7)
  some_string = ~ / something /

    Avoid using Perl's specified variable style (eg, $ :, $; etc.) They are quite mysterious and discourage their use beyond single lines of code.
    Use the friendly alias provided by the English library.

 

  # bad
  $ :. unshift File.dirname (__ FILE__)

  # good
  require 'English'
  $ LOAD_PATH.unshift File.dirname (__ FILE__)

  Never use spaces between method names and (parameter) opening brackets.

  # bad
  f (3 + 2) + 1

  # good
  f (3 + 2) +1

    If the first parameter of the method starts with an open parenthesis, usually use parentheses to enclose them all. For example, f ((3 + 2) + 1).

    The -w option is usually used to run the Ruby interpreter. Ruby will prompt you if you forget the rules mentioned above.

    Define single-line blocks using the new lambda syntax. Define multi-line blocks to use lambda method.

   

 # bad
  l = lambda {| a, b | a + b}
  l.call (1, 2)

  # correct, but looks extremely awkward
  l =-> (a, b) do
   tmp = a * 7
   tmp * b / 50
  end

  # good
  l =-> (a, b) {a + b}
  l.call (1, 2)

  l = lambda do | a, b |
   tmp = a * 7
   tmp * b / 50
  end

    Use proc instead of Proc.new.

  # bad
  p = Proc.new {| n | puts n}

  # good
  p = proc {| n | puts n}

  Anonymous methods and blocks use proc.call () instead of proc [] or proc. ().

  # bad-looks similar to Enumeration access
  l =-> (v) {puts v}
  l [1]

  # also bad-uncommon syntax
  l =-> (v) {puts v}
  l. (1)

  # good
  l =-> (v) {puts v}
  l.call (1)

    Unused block parameters and local variables use _. It is also acceptable to use _ (even if it is less descriptive).
    This convention is organized by the Ruby interpreter and tools like RuboCop which will suppress their unused parameter warnings.

    

# bad
  result = hash.map {| k, v | v + 1}

  def something (x)
   unused_var, used_var = something_else (x)
   # ...
  end

  # good
  result = hash.map {| _k, v | v + 1}

  def something (x)
   _unused_var, used_var = something_else (x)
   # ...
  end

  # good
  result = hash.map {| _, v | v + 1}

  def something (x)
   _, used_var = something_else (x)
   # ...
  end

    Use $ stdout / $ stderr / $ stdin instead of STDOUT / STDERR / STDIN. STDOUT / STDERR / STDIN are constants. Although constants can be reassigned in Ruby (possibly redirected to a stream), the interpreter will warn you if you insist.

    Use warn instead of $ stderr.puts. In addition to being more clear and concise, if you need to,
    warn also allows you to suppress warnings (set the warning level to 0 with -W0).

    Tend to use sprintf and its alias format instead of the rather obscure String #% method.

 

  # bad
  '% d% d'% [20, 10]
  # => '20 10 '

  # good
  sprintf ('% d% d', 20, 10)
  # => '20 10 '

  # good
  sprintf ('% {first}% {second}', first: 20, second: 10)
  # => '20 10 '

  format ('% d% d', 20, 10)
  # => '20 10 '

  # good
  format ('% {first}% (second}', first: 20, second: 10)
  # => '20 10 '

    Tend to use Array # join rather than the rather obscure Array # * that takes strings as parameters.

  

 # bad
  % w (one two three) * ','
  # => 'one, two, three'

  # good
  % w (one two three) .join (',')
  # => 'one, two, three'

    When dealing with variables that you want to treat like Array, but you are not sure it is an array,
    Use [* var] or Array () instead of explicit Array check.

 

  # bad
  paths = [paths] unless paths.is_a? Array
  paths.each {| path | do_something (path)}

  # good
  [* paths] .each {| path | do_something (path)}

  # good (and a bit more readable)
  Array (paths) .each {| path | do_something (path)}

    Try to use ranges or Comparable # between? To replace complex logical comparisons.

  

 # bad
  do_something if x> = 1000 && x <= 2000

  # good
  do_something if (1000..2000) .include? (x)

  # good
  do_something if x.between? (1000, 2000)

    Try to use the predicate method instead of ==. Except for comparative figures.

   

 # bad
  if x% 2 == 0
  end

  if x% 2 == 1
  end

  if x == nil
  end

  # good
  if x.even?
  end

  if x.odd?
  end

  if x.nil?
  end

  if x.zero?
  end

  if x == 0
  end

    Avoid using BEGIN blocks.

    Use Kernel # at_exit. Never use the END block.

  # bad

  END {puts 'Goodbye!'}

  # good

  at_exit {puts 'Goodbye!'}

    Avoid flip-flops.

    Avoid using nested conditions to control the process.
    When you may assert illegal data, use a defensive statement. A defensive statement is a conditional statement at the top of a function, so that if the data is illegal, it can jump out of the function as soon as possible.

   

 # bad
   def compute_thing (thing)
    if thing [: foo]
     update_with_bar (thing)
     if thing [: foo] [: bar]
      partial_compute (thing)
     else
      re_compute (thing)
     end
    end
   end

  # good
   def compute_thing (thing)
    return unless thing [: foo]
    update_with_bar (thing [: foo])
    return re_compute (thing) unless thing [: foo] [: bar]
    partial_compute (thing)
   end

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.