ruby - oyaji's Blog
2010年十本计算机软件开源图书
-
2010年十本计算机软件开源图书- http://progit.org/book/zh/
- http://eloquentjavascript.net/
- http://railstutorial.org/ruby-on-rails-tutorial-book
- http://rails-nutshell.labs.oreilly.com/
- http://guides.rubyonrails.org/
- http://ruby.runpaint.org/ https://github.com/runpaint/read-ruby
- http://vim.runpaint.org/ https://github.com/runpaint/vim-recipes
- http://ofps.oreilly.com/titles/9781449380373/
- http://blog.envylabs.com/Rails_3_Cheat_Sheets.pdf
- http://www.sapphiresteel.com/IMG/pdf/LittleBookOfRuby.pdf
ruby编码规范
前言
本blog是在ruby编程的基础上说明的。在实际的项目中,适当修改本规范使其更适合项目的需要。
source格式
if x > 0 if y > 0 puts "x > 0 && y > 0" end end
2. 一行中的最大字符数 在一行中输入的字符数最大为80。
3. 空行 在class之间用空行分隔
正
class Foo ... end class Bar ... end
误
class Foo ... end class Bar ... end
另外,在class内部的各种组成单元间用空行分隔
class Foo attr :bar def baz ... end def quux .. end end
4. 注释 方法定义的内部不追加注释。(当你认为有需要注释的代码的地发,请refactoring) 但class,module等的public方法的功能说明请在RDoc中注明
# 拆分逗号分隔的字符串、结果作为数组返回 def split_csv(str) return str.split(/,/) end
构文规范
1. class的构成要素 class的构成要素请按下面的顺序来依次进行
1. include module
2. 定义常数
3. 定义类变量,类的实例变量
4. 定义public属性的类方法
5. 定义accessor
6. 定义initialize
7. 定义public的实例方法
8. 定义protected的类方法
9. 定义protected的access
10.定义protected的实例方法
11.定义private的类方法
12.定义private的access
13.定义private的实例方法
2. 定义accessor
accessor是指attr_accessor,attr_reader,attr_writer这几个方法
3. 定义方法
定义方法时其参数要用()括起来。但没有参数的时候,不要加()
def foo(x, y) ... end def foo ... end
4. 定义类方法
使用self来定义类方法
正
class Foo def self.foo ... end end
误
class Foo def Foo.foo ... end end
5. 方法调用
调用方法时要用()将参数括起来。但如果没有参数时不要加()。
但在调用puts,print,p这几个方法时,参数不用()
正
foo(1, "abc") obj.foo(1, "abc") bar print "x = ", x, "\n"
误
foo 1, "abc" obj.foo 1, "abc" bar()
6. block 针对block基本原则是使用do...end
正
foo(x, y) do ... end x = bar(y, z) do ... end
误
foo(x, y) { ... } x = bar(y, z) { ... }
但如是行内嵌入的场合,请使用{}
正
s = ary.collect { |i| i.to_s }.join(",")
误
s = ary.collect do |i| i.to_s end.join(",")
7. return 要返回方法的值的时候,请使用明确使用return。但请省略()
正
def add(x, y) return x + y end
误
def add(x, y) x + y end def add(x, y) return(x + y) end
8. yield
通过yield来调用方法的写法,请参考方法调用
9. 条件分支
if后面的then可以省略。在if !x的判断时,请用unless x来代替,但unless的情况下不要使用else。
正
if x > 0 puts "x > 0" else puts "x <= 0" end unless x puts "x is false" end puts "x is true" if x
误
if x > 0 then puts "x > 0" end unless x puts "x is false" else puts "x is true" end puts "foo && bar && baz && quux" if foo && bar && baz && quux
10.case 在使用case语句时,省略then
正
case x when 1 ... when 2 ... end
误
if x == 1 ... elsif x == 2 ... end case x when 1 then ... when 2 then ... end
11.不要使用条件分支的值
正
if x > 0 msg = "x > 0" else msg = "x <= 0" end
误
msg = if x > 0 "x > 0" else "x <= 0" end
12.循环处理
省略while的do。另在使用while !x的语句时,请用until x来代替
正
while cond ... end until cond ... end
误
while cond do ... end
13.无限循环时,请使用loop
正
while true ... end
14.逻辑运算符
逻辑运算符有! && || (不要使用not and or)
15.三元运算符
条件复杂,或者需要换行的情况下,不要使用三元运算符
命名规范
1. 全体
1. 原则上不使用单词的缩略写法
2. 作用域较小情况下的循环变量,使用i,j,k并按照这样的顺序来使用
3. 作用域较小情况下的变量密,使用class名称的简写形式也可以
2. 类名,模块名
类名,模块名中每个单词的首字母大写,不要用’_'这样的分隔字符。 但在HTTP等这样的省略语的情况下,所有的字母都大写
正
ExampleClass HTTPClient
误
Example_Class EXAMPLE_CLASS HttpClient HTTPclient HTTP_Client
3. 方法名
方法名中全部的字母都要小写,单词之间用’_'这样的分隔字符。
正
add_something
误
addsSomething Add_Something
方法名中请使用动词的原形 返回的值是true/false的情况下,动词或者形容词后面加上?。不要用is_这样的写法
正
visible?
误
is_visible is_visible?
如果,对可能改变传入参数的方法后面加上!
split split! # split带有破坏性的版本
4. 常量名
类名模块名之外的常量定义时,全部字符大写,单词之间用’_'这样的分隔字符。
EXAMPLE_CONSTANT
5. 变量名
全部字符小写,单词之间用’_'这样的分隔字符。
tmp local_variable @instance_variable $global_variable
6. 文件名
文件名全部小写,单词之间用’_'这样的分隔字符。 使用文件中主要的类名经变化之后,作为文件名
foo.rb # 定义foo类 foo-bar.rb # 定义foo-bar类 foo/bar-baz.rb # 定义Foo::BarBaz类(命名空间中的class)
RUBY中使用YAML
require 'yaml' # 必须 obj.to_yaml # 转化成YAML格式
obj = ... decoded_obj = YAML::load(obj.to_yaml)
obj = ... # 略 bin = Marshal.dump(obj) # 将ruby对象转化成binary格式 loaded_obj = Marshal.load(bin) # 将binary格式的对象还原 require 'yaml' yml = obj.to_yaml # 将ruby对象转化成YAML格式 loaded_obj = YAML::load(yml) # 将YAML格式的对象还原
require 'yaml/store' db = YAML::Store.new('yaml_db') db.transaction{ db['data'] = obj val1 = db['val1'] }
ruby 基本知识学习
1. proc
#Proc.new {|x| puts x}
#|x|就相当于一个变量了,这个变量的值是Proc.call()里传递过来的
greeting = Proc.new {|someone| puts "Hi, #{someone}"}
greeting.call("Lily") ---输出:Hi,Lily
def add(m)
return Proc.new {|n| n + m }
# return lambda {|n| n + m } ---也可以写成这样,lambda将一个block转化成proc对象
end
add10 = add(10) --- m = 10
add100 = add(100) --- m = 100
print "40 + 10 = "
puts add10.call(40) --- n = 40
print "427 + 100 = "
puts add100.call(427) --- n = 427
2. closure
闭包:即使block被定义时的环境早就消失了,block仍然可以使用其原始作用域中的信息。
比如上例中的
add10 = add(10) --- m = 10
puts add10.call(40) --- n = 40
其实:add10对象就是用10这个参数来构造的,那自然在add10这个实例中始终知道10的存在,
所以在add10.call()时可以使用10
呵呵,个人理解。和著述不一致:)