使用 :: 引用常量(包括类和模块)和构造器 (比如 Array() 或者 Nokogiri::HTML())。
    永远不要使用 :: 来调用方法。

  # bad
  SomeClass::some_method
  some_object::some_method

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

    使用括号将def的参数括起来。当方法不接收任何参数的时候忽略括号。

     

# 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

    从来不要使用 for, 除非你知道使用它的准确原因。大多数时候迭代器都可以用来替for。for 是由一组 each 实现的 (因此你正间接添加了一级),但是有一个小道道 - for并不包含一个新的 scope (不像 each)并且在它的块中定义的变量在外面也是可以访问的。

 

  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'

    在多行的 if/unless 中坚决不要使用 then。

    

# bad
  if some_condition then
   # body omitted
  end

  # good
  if some_condition
   # body omitted
  end

    在多行的 if/unless 总是把条件放在与 if/unless 的同一行。

 

  # bad
  if
   some_condition
   do_something
   do_something_else
  end

  # good
  if some_condition
   do_something
   do_something_else
  end

    喜欢三元操作运算("htmlcode">

  # bad
  result = if some_condition then something else something_else end

  # good
  result = some_condition "htmlcode">
  # bad
  some_condition "htmlcode">
  # bad
  result = if some_condition then something else something_else end

  # good
  result = some_condition "htmlcode">
  # bad
  if condition
   result = x
  else
   result = y
  end

  # good
  result =
   if condition
    x
   else
    y
   end

    在 one-line cases 的时候使用 when x then ...。替代的语法when x: xxx已经在Ruby 1.9中移除。

    不要使用when x; ...。查看上面的规则。

    使用 ! 替代 not.

    

# 差 - 因为操作符有优先级,需要用括号。
  x = (not something)

  # good
  x = !something

  避免使用 !!.

  # 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"htmlcode">
 # bad
  # boolean expression
  if some_condition and some_other_condition
   do_something
  end

  # control flow
  document.saved"htmlcode">
# bad
  if some_condition
   do_something
  end

  # good
  do_something if some_condition

  # another good option
  some_condition && do_something

    布尔表达式使用&&/||, and/or用于控制流程。(经验Rule:如果你必须使用额外的括号(表达逻辑),那么你正在使用错误的的操作符。)

   

 # boolean expression
  if some_condition && some_other_condition
   do_something
  end

  # control flow
  document.save"htmlcode">
 # bad
  if some_condition
   do_something
  end

  # good
  do_something if some_condition

  # another good option
  some_condition and do_something

    永远不要使用 unless 和 else 组合。将它们改写成肯定条件。

    

# bad
  unless success"htmlcode">
  # bad
  if (x > 10)
   # body omitted
  end

  # good
  if x > 10
   # body omitted
  end

    在多行 while/until 中不要使用 while/until condition do 。

   

 # 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

    当你有单行主体时,尽量使用 while/until 修饰符。

  # bad
  while some_condition
   do_something
  end

  # good
  do_something while some_condition

    否定条件判断尽量使用 until 而不是 while 。

  

 # bad
  do_something while !some_condition

  # good
  do_something until some_condition

    循环后条件判断使用 Kernel#loop 和 break,而不是 begin/end/until 或者 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

    忽略围绕内部 DSL 方法参数的括号 (如:Rake, Rails, RSpec),Ruby 中带有 "关键字" 状态的方法(如:attr_reader,puts)以及属性存取方法。所有其他的方法调用使用括号围绕参数。

    

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

    忽略隐式选项 hash 外部的花括号。

  

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

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

    内部 DSL 方法的外部括号和大括号。

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

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

    方法调用不需要参数,那么忽略圆括号。

 

  # bad
  Kernel.exit!()
  2.even"htmlcode">
  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"htmlcode">
  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

    避免在不需要流的控制使用 return。

 

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

  # good
  def some_method(some_arr)
   some_arr.size
  end

    避免在不需要的地方使用 self(它仅仅在调用一些 self 做写访问的时候需要)(It is only required when calling a self write accessor.)

    

# bad
  def ready"htmlcode">
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

    不要在条件表达式里使用 = (赋值)的返回值,除非条件表达式在圆括号内被赋值。
    这是一个相当流行的 ruby 方言,有时被称为 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

    在任何可以的地方使用快捷的 self assignment 操作符。

   

 # 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

    只有在变量没有被初始化的时候使用 ||= 来初始化变量。

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

    不要使用||=来初始化布尔变量。(想想如果当前值为false的时候会发生什么。)

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

  # good
  enabled = true if enabled.nil"htmlcode">
  # bad
  if something
   something = something.downcase
  end

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

  # good
  something.is_a"htmlcode">
  # bad
  $:.unshift File.dirname(__FILE__)

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

  从来不要在方法名和(参数)开括号之间使用空格。

  # bad
  f (3+2) + 1

  # good
  f(3 + 2) +1

    如果方法的第一个参数以开括号开始,通常使用括号把它们全部括起来。例如f((3 + 2) + 1)。

    通常使用 -w 选项运行 Ruby 解释器,在你忘记上面所诉规则,ruby 将会提示你。

    定义单行块使用新的 lambda 语法。定义多行块中使用 lambda 方法。

   

 # 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

    用 proc 而不是 Proc.new。

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

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

  匿名方法 和 块 用 proc.call() 而不是 proc[] 或 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)

    未使用的块参数和局部变量使用 _。它也可以接受通过 _ 来使用(即使它有少了些描述性)。
    这个惯例由 Ruby 解释器以及 RuboCop 这样的工具组织其将会抑制它们的未使用参数警告。

    

# 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

    使用 $stdout/$stderr/$stdin 而不是 STDOUT/STDERR/STDIN。STDOUT/STDERR/STDIN 是常量,虽然在 Ruby 中是可以给常量重新赋值的(可能是重定向到某个流),但解释器会警告如果你执意这样。

    使用 warn 而不是 $stderr.puts。除了更加清晰简洁,如果你需要的话,
    warn 还允许你抑制(suppress)警告(通过 -W0 将警告级别设为 0)。

    倾向使用 sprintf 和它的别名 format 而不是相当隐晦的 String#% 方法.

 

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

    倾向使用 Array#join 而不是相当隐晦的使用字符串作参数的 Array#*。

  

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

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

    当处理你希望像 Array 那样对待的变量,但是你不确定它是一个数组时,
    使用 [*var] or Array() 而不是显式的 Array 检查。

 

  # bad
  paths = [paths] unless paths.is_a"htmlcode">
 # bad
  do_something if x >= 1000 && x <= 2000

  # good
  do_something if (1000..2000).include"htmlcode">
 # bad
  if x % 2 == 0
  end

  if x % 2 == 1
  end

  if x == nil
  end

  # good
  if x.even"htmlcode">
  # bad

  END { puts 'Goodbye!' }

  # good

  at_exit { puts 'Goodbye!' }

    避免使用 flip-flops 。

    避免使用嵌套的条件来控制流程。
    当你可能断言不合法的数据,使用一个防御语句。一个防御语句是一个在函数顶部的条件声明,这样如果数据不合法就能尽快的跳出函数。

   

 # 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

标签:
Ruby,语法,风格

免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com
评论“Ruby编程中的语法使用风格推荐”
暂无“Ruby编程中的语法使用风格推荐”评论...

稳了!魔兽国服回归的3条重磅消息!官宣时间再确认!

昨天有一位朋友在大神群里分享,自己亚服账号被封号之后居然弹出了国服的封号信息对话框。

这里面让他访问的是一个国服的战网网址,com.cn和后面的zh都非常明白地表明这就是国服战网。

而他在复制这个网址并且进行登录之后,确实是网易的网址,也就是我们熟悉的停服之后国服发布的暴雪游戏产品运营到期开放退款的说明。这是一件比较奇怪的事情,因为以前都没有出现这样的情况,现在突然提示跳转到国服战网的网址,是不是说明了简体中文客户端已经开始进行更新了呢?