1、Ruby 代码风格向导分类: Ruby2011-12-04 23:16 329 人阅读 评论(0) 收藏 举报公司推荐 https:/ 这个 Ruby 风格向导不错。我这边学习一下与大家共勉之。蓝色字部分是我的个人理解。有不对之处,还请大家指出。请记住下面的名言。html view plaincopy1. 风格可以使一个好代码转变为伟大的代码。 2. 3. - Bozhidar Batsov 这个 Ruby 风格指南是推荐编写最佳的 ruby 代码风格。这样的话每个程序员写得代码都可以也其他程序员维护。代码风格可以帮助世界上的人理解你的代码。但是不管什么样的代码风格都会被一些人认为有风险而拒绝
2、使用。该指南分为几个部分的相关规则。我尝试过添加规则背后的原因(如果它被省略,我假设是很明显的的)。我没有把所有的代码风格都列出来。这些都是我作为一个软件工程师,在工作中从 ruby 交流社区得到的建议,反馈。以及一些备受推荐的 ruby 资源。就像 “Programming Ruby 1.9“和 “The Ruby Programming Language“.这些规则有些正在写,有些缺少些例子。有些显而易见的就没有添加例子。在适当的时候,这些问题将得到解决-他们现在只需记住。=源代码布局=注:每个人都相信别人的代码风格是正确的,而自己是丑陋的,不可读。但是有时候他们也有可能是对的。-Jerr
3、y Coffin这句话的意思大家不能过分相信代码风格向导,有时候还是需要一些自信,你的代码风格也有可能是正确的。1. 使用 UTF-8 作为代码编码一般 ruby 程序是在头上设定“# encoding: UTF-8“的方式来指定编码。个人理解在 rails 里面就是在数据库设定里面指定编码为 UTF-8 就可以了。2.使用 2 个空白作为代码缩进html view plaincopy1. # 好的缩进 2 个空白 2. def some_method 3. do_something 4. end 5. 6. # 不好的缩进 - 4 个空白 7. def some_method 8. do_s
4、omething 9. end 这个不用我解释了。比较简单。3.结束符使用 unix 风格的 (*BSD/Solaris/Linux/OSX 用户不要担心,因为系统是默认的,Windows 用户需要格外小心.)你如果使用 git 管理代码的话,可以加入下面的设置保证你代码中不会有windows 换行符侵入。html view plaincopy1. $ git config -global core.autocrlf true 个人认为是 ruby 是以 LF 认为换行。所以在代码中的换行要注意。windows 下以 CR/LF 表换行,而 linux 的换行符 LF4.在操作符左右,逗号,冒
5、号,分号后面以及“前后,“前面使用空白.空白可能和 ruby 解释器无关,但它可以使代码读起来更加轻松。html view plaincopy1. sum = 1 + 2 2. a, b = 1, 2 3. 1 2 ? true : false; puts Hi 4. 1, 2, 3.each |e| puts e 唯一的例外是你如果使用指数运算符时,不需要空白。html view plaincopy1. # 不好的 2. e = M * c * 2 3. 4. # 好的 5. e = M * c*2 5.不要在“(”,“ “之后或者”“,“)“ 之前使用空白html view plainco
6、py1. some(arg).other 2. 1, 2, 3.length 6.case 和 when 的缩进一样可能很多人不同意这样的观点,但是“The RubyProgramming Language“ 和 “Programming Ruby“都是这么写的。html view plaincopy1. case 2. when song.name = Misty 3. puts Not again! 4. when song.duration 120 5. puts Too long! 6. when Time.now.hour 21 7. puts “Its too late“ 8. e
7、lse 9. song.play 10. end 11. 12. kind = case year 13. when 18501889 then Blues 14. when 18901909 then Ragtime 15. when 19101929 then New Orleans Jazz 16. when 19301939 then Swing 17. when 19401950 then Bebop 18. else Jazz 19. end 7。使用空行在 def 之间和代码逻辑块之间html view plaincopy1. def some_method 2. data =
8、initialize(options) 3. 4. data.manipulate! 5. 6. data.result 7. end 8. 9. def some_method 10. result 11. end 8.使用 RDoc 并且他能转化为 API 文档。不要在注释块和 def 之间使用空行。9.保持每行代码不超过 80 字节长度10.避免尾随空白就是代码结束的地方不要加空白。=语法=1. def 函数有参数的时候请用括号。没有参数的时候可以省略括号。ruby view plaincopy1. def some_method 2. # body omitted 3. end 4.
9、5. def some_method_with_arguments(arg1, arg2) 6. # body omitted 7. end 2. 请不要使用 for.除非你有充分的理由。一般情况下是迭代器可以代替 for的。For 是 each 的一种实现。所以你使用 for 只是间接调用 each。但是 for 没有block 块。这点和 each 不一样。并且 for 循环里面定义的变量对于外部是可以访问的。ruby view plaincopy1. arr = 1, 2, 3 2. 3. # bad 4. for elem in arr do 5. puts elem 6. end 7
10、. 8. # good 9. arr.each |elem| puts elem 3. 多行使用 if/unless 的时候请不要使用 thenruby view plaincopy1. # bad 2. if some_condition then 3. # body omitted 4. end 5. 6. # good 7. if some_condition 8. # body omitted 9. end 4. 使用 if/then/else/end 结构的地方请尽量用三元操作符 (?:)代替。因为它能使你的代码更加简洁ruby view plaincopy1. # bad 2. r
11、esult = if some_condition then something else something_else end 3. 4. # good 5. result = some_condition ? something : something_else 5. 三元操作符每一个分支只有一个表达式。也就是说三元操作符的分支表达式里面不应该有嵌套。在这种情况下,请尽量使用 if/else。ruby view plaincopy1. # bad 2. some_condition ? (nested_condition ? nested_something : nested_someth
12、ing_else) : something_else 3. 4. # good 5. if some_condition 6. nested_condition ? nested_something : nested_something_else 7. else 8. something_else 9. end 6. 请不要使用 ifx: .表达式。因为在 ruby 1.9 里面已经去除了。请用三元操作符代替。同样 if x;也一样不推荐使用。ruby view plaincopy1. # bad 2. result = if some_condition: something else so
13、mething_else end 3. 4. # good 5. result = some_condition ? something : something_else 7. 一行的 case 语句请用 when x then .语句。请不要使用 when x: .语句。因为 ruby 1.9 里面已经废弃掉了。同样的 when x;也不要使用。8. 布尔变量判断请用”&/|”。控制流程判断请用 “and/or”ruby view plaincopy1. # boolean expression 2. if some_condition & some_other_condition 3. d
14、o_something 4. end 5. 6. # control flow 7. document.saved? or document.save! 9.多行代码的情况下请尽量避免使用三元操作符。而是使用 if/unless 代替。10.如果你的 if/unless 后的操作代码只有一行。请不要写多行,一行就可以了。另外一种好的写法是用 and 代替。ruby view plaincopy1. # bad 2. if some_condition 3. do_something 4. end 5. 6. # good 7. do_something if some_condition 8.
15、 9. # another good option 10. some_condition and do_something 11. 相反条件的判断不要使用 if 而是使用 unless 代替。或者用 or 也可以代替。ruby view plaincopy1. # bad 2. do_something if !some_condition 3. 4. # good 5. do_something unless some_condition 6. 7. # another good option 8. some_condition or do_something 12. 不要把 unless
16、和 else 在一起使用。可以用正常逻辑重写代码。ruby view plaincopy1. # bad 2. unless success? 3. puts failure 4. else 5. puts success 6. end 7. 8. # good 9. if success? 10. puts success 11. else 12. puts failure 13. end 13. 请不要在 if/unless/while 的条件外面加上括号。ruby view plaincopy1. # bad 2. if (x 10) 3. # body omitted 4. end 5
17、. 6. # good 7. if x 10 8. # body omitted 9. end 14. 调用内部 DSL(例如 Rake, Rails, RSpec),还有一些关键字的方法是可以省略括号的。其他方法调用的时候都不能省略括号。ruby view plaincopy1. class Person 2. attr_reader name, age 3. 4. # omitted 5. end 6. 7. temperance = Person.new(Temperance, 30) 8. temperance.name 9. 10. puts temperance.age 11. 1
18、2. x = Math.sin(y) 13. array.delete(e) 15. 单行的 block 使用“”。多行的时候避免使用 ”。一般是用 doend 作为控制流程和一些方法(Rakefiles and certain DSLs)定义。避免使用 doend 有链接方法的时候。ruby view plaincopy1. names = “Bozhidar“, “Steve“, “Sarah“ 2. 3. # good 4. names.each |name| puts name 5. 6. # bad 7. names.each do |name| 8. puts name 9. en
19、d 10. 11. # good 12. names.select |name| name.start_with?(“S“) .map |name| name.upcase 13. 14. # bad 15. names.select do |name| 16. name.start_with?(“S“) 17. end.map |name| name.upcase 16.尽量避免使用 return。ruby view plaincopy1. # bad 2. def some_method(some_arr) 3. return some_arr.size 4. end 5. 6. # go
20、od 7. def some_method(some_arr) 8. some_arr.size 9. end 17.在方法的参数设置默认值的=操作符两边请加入空白ruby view plaincopy1. # bad 2. def some_method(arg1=:default, arg2=nil, arg3=) 3. # do something. 4. end 5. 6. # good 7. def some_method(arg1 = :default, arg2 = nil, arg3 = ) 8. # do something. 9. end 18.尽量避免使用换行符()。ru
21、by view plaincopy1. # bad 2. result = 1 - 3. 2 4. 5. # good (but still ugly as hell) 6. result = 1 7. - 2 19.使用=取得返回值是可以的。ruby view plaincopy1. if v = array.grep(/foo/) . 20.可以自由使用|=来初始化变量。ruby view plaincopy1. # set name to Bozhidar, only if its nil or false 2. name |= Bozhidar 21.不要使用|=来初始化布尔型变量。r
22、uby view plaincopy1. # bad - would set enabled to true even if it was false 2. enabled |= true 3. 4. # good 5. enabled = true if enabled.nil? 22.避免使用 Perl-style 特殊的变量。例如($0-9, $等)23.在调用方法的时候,请不要在方法名和括号之间加空格ruby view plaincopy1. # bad 2. f (3 + 2) + 1 3. 4. # good 5. f(3 + 2) + 1 24.如果方法的第一个参数有括号,请使用
23、括号在方法调用的时候。例如f(3 + 2) + 1)25.在 ruby 代码运行时候,请加上w 运行选项。他可以提醒你,如果你忘记上面的规则的话。=命名=1. 方法名和变量命名使用 snake case。snake case = 单词之间用下划线连接。单词要么全部大写,要么全部小写。2. 定义类和模块名字使用 CamelCase。CamelCase = 每个单词的首字母为大写,空格和标点符号删除。3. 常量命名使用 SCREAMING_SNAKE_CASESCREAMING_SNAKE_CASE= 全部大写的 snakecase4. 一个返回布尔型的方法命名的结尾请加上问号?.5. 有潜在危险
24、的方法的命名请在结尾加上感叹号!有潜在危险的方法 = 改变自己或者参数的方法6. 使用 inject 方法时,命名参数为 |a,e|(accumulator, element).7. 如果定义二元运算符方法时,参数命名为 otherruby view plaincopy1. def +(other) 2. # body omitted 3. end 8. 使用 map 优于 collect,find 优于 detect,select 优于 find_all,size优于 length.这不是硬性规定。如果使用别名能增强可读性,那就可以使用。=注释=良好的代码就是最好的注释。当你想要增加注释的时
25、候,问问你自己,怎么样提高代码的质量那样就没有必要写注释呢?1.如果可以写出高质量的代码,你可以忽略这节的其他部分。2.注释比较长的话,请注意首字母大写,或者加标点符号。单词之间有空格。3.避免冗余的注释ruby view plaincopy1. # bad 2. counter += 1 # increments counter by one 4. 保持注释是最新的。没有注释都比过期的注释好。5. 避免写注释来解释烂代码。应该重构代码让他能够更加易读。=注解=1. 注解一般写在相关代码的上面。并且紧挨在一起。2. 注解一般写在#和一个空白之后,然后描述问题3. 如果注解要写多行,第二行必须在
26、#之后缩进 2 个空白ruby view plaincopy1. def bar 2. # FIXME: This has crashed occasionally since v3.2.1. It may 3. # be related to the BarBazUtil upgrade. 4. baz(:quux) 5. end 4. 如果问题很明显,写任何的注解有点冗余。这时候可以写在代码后面,不需要写任何注解。这个是特殊情况不是规则。ruby view plaincopy1. def bar 2. sleep 100 # OPTIMIZE 3. end 5. TODO 一般是表示缺少某
27、些功能,以后将会完成。6. FIXME 一般表示代码这块会引起中断,需要被解决。7. OPTIMIZE 一般表示这段代码效率有问题,有性能问题。8. HACK 表示感觉这段代码很可疑有问题,需要重构。9. REVIEW 表示这段代码需要被别人确认是否达到预期。10. 如果合适的话,也可以用其他关键字表示注解。但是你一定要确保他们在你的 readme 文件或者其他类似文件里面进行详细说明。=类=1. 始终提供一个适当的方法 to_s.ruby view plaincopy1. class Person 2. attr_reader :first_name, :last_name 3. 4. de
28、f initialize(first_name, last_name) 5. first_name = first_name 6. last_name = last_name 7. end 8. 9. def to_s 10. “#first_name #last_name“ 11. end 12. end 2. 利用 attr 的设定来定义琐碎的访问器或者存取器3. 考虑增加工厂方法提供额外的方法来创建一个特定的类的实例。4. 尽量使用鸭子类型而不是继承。(多态)5. 避免使用 类变量因为他们在继承里面会引起 Bug。6. 定义方法的时候请根据各个方法的使用范围确定他们的 scope。到底是
29、public,private,protect 的请注明。而不是全部是 public。7. public,private,protect 缩进是和方法缩进一样的。在上面要空一行。8. 请使用 self 定义类方法。这样的话这些方法更有抵抗性。ruby view plaincopy1. class TestClass 2. # bad 3. def TestClass.some_method 4. # body omitted 5. end 6. 7. # good 8. def self.some_other_method 9. # body omitted 10. end 11. 12. #
30、Also possible and convenient when you 13. # have to define many singleton methods. 14. class “foo”,”bar”,”baz”3. 避免创建的数组的元素有巨大差异4. 如果有很多元素的话请使用 Set 而不是 Array5. hash 的 key 请用 symbols 而不是 string6. 避免使用动态的对象作为 hash 的 key7. 如果你使用 ruby 1.9,请使用新的语法定义 hash。而不是用旧的方式。ruby view plaincopy1. # old way that stil
31、l works in Ruby 1.9 2. my_hash = :a = apple, :b = banana 3. 4. # new way 5. my_hash = a: apple, b: banana 9. 在 ruby 1.9 里面 hash 的 key 不会自动排序了。按照插入的顺序的。10. 遍历集合的时候,请不要修改他。=字符串=1. 字符串连接尽量使用嵌入,而不是+ 号。ruby view plaincopy1. # bad 2. email_with_name = user.name + 3. 4. # good 5. email_with_name = “#user.n
32、ame “ 2. 如果定义一个字符串,这个字符串不需要嵌入或者特殊字符的话,请用单引号字符串ruby view plaincopy1. # bad 2. name = “Bozhidar“ 3. 4. # good 5. name = Bozhidar 3. 实例变量进行字符串嵌入的时候,花括号可以省略。ruby view plaincopy1. class Person 2. attr_reader :first_name, :last_name 3. 4. def initialize(first_name, last_name) 5. first_name = first_name 6.
33、 last_name = last_name 7. end 8. 9. # bad 10. def to_s 11. “#first_name #last_name“ 12. end 13. 14. # good 15. def to_s 16. “#first_name #last_name“ 17. end 18. end 4. 字符串连接请用 String#Some text) 3. # should be Some text 4. 5. # bad (no double-quotes) 6. %(This is #quality style) 7. # should be “This
34、is #quality style“ 8. 9. # bad (multiple lines) 10. %(n#exclamationn) 11. # should be a heredoc. 12. 13. print #name) 3. 当你的正则表达式里面含有 2 个以上的/的字符的时候才使用 %rruby view plaincopy1. # bad 2. %r(s+) 3. 4. # still bad 5. %r(/(.*)$) 6. # should be /(.*)$/ 7. 8. # good 9. %r(/blog/2011/(.*)$) 4. 避免使用 %q, %Q, %
35、x,%s 和 %W.%Q 替代双引号%q 替代单引号%s 定义 symbols%x 运行系统命令%W 定义双引号的字符串数组5. 对于所有的%请使用()作为分割符=杂项=1. 运行时候用 ruby w 来确保你的代码安全2. 避免用 hash 作为方法的可选参数。是不是方法做的事情太多了。3. 避免方法的长度超过 10 行。理想情况下,大多数方法是少于 5 行的。空行不包含在内。4. 避免方法的参数太长。比如,3,4 个参数。5. 你如果想增加全局方法到内核里面。请保持他们是 private 的。6. 使用实例变量代替全局变量ruby view plaincopy1. #bad 2. $foo_bar = 1 3. 4. #good 5. class Foo 6. class Object