1)rails自动生成的目录中,lib目录和vendor目录分别用于存放你自己编写的组件或者第三方提供的组件,它们需要被你的应用程序用到,但又不专属于你的项目。log目录下存放的是日志文件,日志文件会针对开发环境,测试环境和生产环境分别记录。config目录是用来设置rails的配置的,其中包括用于配置服务器链接的yml文件和运行时环境配置文件等。运行时环境配置可以针对三个环境分别进行设置,公共的部分在config根目录下的environment.rb文件中设置,而针对某个环境的设置,则在config/environments/目录下的development.rb、production.rb、test.rb中进行个性设置。
2)在启动web服务器时,可以通过加上-e选项,指定启动时选用哪个环境
==================================
ruby script/server -e development | test | production
==================================
3)rails里强调“惯例重用配置”,从数据库中的表,到控制器,到模型,再到视图,命名是有关联的!文件的存放路径也是有关联的。我们在命名和存放文件时需要遵守这种惯例。一旦我们遵守了这种惯例这四者之间的映射都是rails自动替我们去完成的,这也是rails为何能“敏捷”的重要原因。
4)在编写普通ruby代码时,如果我们想要使用另一个文件中的类和模块,需要先require它们,但在rails中编程,因为rails有命名约定,所以可以不用require它们就直接使用,rails会根据命名约定(也包括路径约定),去自动加载该文件!不过,也有例外的时候,如果被引用的类要在session中保存,自动加载就会失效,但即便如此,我们也仍然不需要require,我们只需要在类里加上一句 model :类文件名(注,小字加下划线分隔)。
==================================
class StroeController < ApplicationController
model :line_item #rails会去加载line_item.rb文件,其中包含LineItem类。
==================================
5)控制器的路径默认是存放在app/controllers根目录下的,但如果我们需要在根目录下再组织一下控制器的路径,那么可以将控制器的声明位于ruby模块之下。例如,我们要将book_controller.rb文件放置于admin目录下,也就是app/controllers/admin/book_controller.rb,那么,我们就应该这样声明:
==================================
class Admin::BookController < ApplicationController
..
end
==================================
幸运的是,rails的生成器很智能,你可以直接使用
==================================
ruby script/generate controller Admin::Book action1 action2
==================================
来生成你需要的路径。
6) rails用ActiveRecord来处理对象-关系映射(ORM)。数据库中的一张表对应着模型中的一个类,表名是小写的,多单词用下划线分隔,而且是复数形式。对应的类名是单词首字母大写来进行分隔的,而且是单数形式。表中的字段直接映射成类的属性,除此之外,我们还可以给类再另外添加一些属性。表名和类名是通过命名惯例去自动对应的,(rails对ruby的字符串类进行了扩展,让它直接支持单复数之间的转变,例如 puts “cat”.pluralize #=>cats puts “cats”.singularize #=>cat),仅管pluralize和singularize方法已经很智能了,能处理child和children这样的单复数转换,但它仍然还是有缺陷,例如sheep会对应到sheeps。我们可以在模型类中,cefpset_table_name去显示地指明对应的表,而不使用缺省的惯例。
==================================
class Sheep < ActiveRecord::Base
set_table_name “sheep”
end
==================================
7)ActiveRecord从表中取出值,变成类的对象时,会自动将数据库中的类型转换成ruby支持类型,例如数据库字段是timestamp类型的,就会返回Time对象。如果你希望得到一个属性的原始值,可以在属性名称后面加上_before_type_cast。
==================================
account.balance_before_type_cast
==================================
如果在模型内部,可以使用私有方法read_attribute()和write_attribute()。
8)布尔型的数据在转换的时候会有些麻烦,有些数据库是不支持布尔型的,所以我们在工作中,可以使用0,1这样的数字来代表布尔值的真假,而ruby中只有false和nil为假,0其实是为真的。所以在数据库映射到类时,我们要判断某个属性的真假时,记得要加一个?号,这个是rails为解决布尔型问题而设置的。
==================================
# 错误写法
if user.superuser
doSomeThing
end
# 正确写法
if user.superuser?
doSomeThing
end
==================================
9) 在编程时,可以某个属性对应的是一个对象,而不是一个简单类型的数据。在类和表的映射的时候,这种复杂类型的属性也是可以直接保存到表中的一个字段的,这个字段必须是text类型的,属性会以字符串的形式存进数据据。而从数据库中映射到类时,需要在类中加以声明,某个字段是个对象,不是普通字符串。声明的方法是serialize()。复杂类型包括对象,数组,hash等等。
==================================
class Purchase < ActiveRecord::Base
serialize :last_five
…
end
==================================
10)主键。一般来说,rails都会用id作为每张表的主键,但表并不是由我们自己来建的,可能表会用别的字段作为主键。我们可以用set_primary_key来显示地指定主键字段。
==================================
class BadBook < ActiveRecord::Base
set_primary_key “isbn”
end
==================================
但需要注意的是,既然指定主键为其它字段,但在访问时,仍然可以通过名为id的属性来设置主键值,也就是说,只要使用ActiveRecord,主键字段在对象中的属性名称就永远都是id。

1) 在windows系统上安装rails很简单,首先需要安装ruby,完整安装,然后先在命令行输入gem –version,如果显示出版本号,就可以直接使用RubyGems来安装rails。直接在命令行输入 gem install rails –include-dependencies就可以自动完成安装了。需要注意的是,在windows系统上配置ror环境,还会出现一些奇怪的问题,具体安装过程推荐一篇博客:http://hi.baidu.com/haoweiren1234/blog/item/1d84b53875b8ea2cb9998f79.html,博主讲解得非常清楚。
2) ruby和其它服务器端语言一样,可以运行动态脚本,格式是<% %>。如果想输出显示,可以使用<%= %>。ruby的服务器使用的是WEBrick,不是appache,不是IIS,不是tomcat哦。
3)用rails新建一个项目很简单,在命令行输入 rails xxx,xxx就是项目的根目录文件夹名。然后rails会为你自动创建好目录结构,并提供好部分代码。rails提倡的敏捷开发,很大意义上依靠于这种带有“强制性”的自动操作。rails会为你建好目录,搭好框架,我们需要做的,只是填充框架里的内容。不用置疑rails自动搭建的框架是否优秀,是否弹性十足,是否可维护性良好。rails的敏捷开发目标,目的就是为了搭一个最优势的框架。
4)新建项目之后,在命令行输入 ruby script/server,运行rails自动为我们生成的代码中的server脚本,就可以启动WEBrick服务器了。
|

String 类
1)单引号和双引号。 单引号不会对里面的字符进行转义,类似于”\n”这样的转义会直接输出,也不能包含表达式。双引号则可以包含转议字符,也能包含表达式,表达式的格式为 #{xxxx}。需要注意的是,如果单引号里的字符串也包含单引号,还是要用“\’”进行转义的,这个转义是支持的。
=======================
a = “abc”
b = “1\n2\n3\n#{a}”
c = ‘1\n2\n3\n#{a}’
puts b #=> 1 2 3 abc
puts c #=> 1\n2\n3\n#{abc}
=======================
2) 新建字符串。
<1> 直接使用 “”和”生成字符串。
<2> 使用String.new()生成字符串。
<3> 使用%Q和%q。 如果字符串中包括”"或”时,不想使用\”和\’频繁转义,可以使用%Q和%q来生成字符串。其中%Q相当于”,%q相当于’。和%w一样,分界符可以用<> @@之类的。
=======================
%Q(1\n2\n3\n#{a}”5678″‘9012′)
%q<1\n2\n3\n#{a}’5678′”9012″>
=======================
<4> 如果是多行文本,可以使用<<”xxx” 或 <<-”xxx”来实现多行。一般xxx多使用EOB或EOF,表示end of black和end of file。注意,如果是xxx可以用单引号或双引号引起来,分别代表单引和双引,也可以不带引号,默认代表双引。注意<<和xxx之间要连在一起,不要有空格。
======================
a = 123
s = <<-”EOB”
i : abc
j : #{a}
adang is me
EOB
print s #=> i : abc
j : 123
adang is me
======================
3) 字符串的长度。 字符串的长度可以用str.size或者str.length来获得。如果是英文字符,那么可以正常返回字符个数,但如果是非英文字符,比如说是中文字符,size返回的值就不正确了。因为ruby中返回的是字节数,不是字符数,这点和js不同。如果是中文,跟编码格式有关,如果是utf-8编码,那么一个中文占用三个字节,如果是ANSI编码,那么一个中文占用两个字节。为了解决这个问题,可以借助于正则表达式,换个思路获得字符串的字符长度。例如utf-8编码的,用str.split(//u).length,ANSI编码的,用str.split(//e).length。
=======================
utf-8编码
a = “我是个中文abc”
puts a.size #=> 18 (5X3+3 = 18)
puts a.split(//u).length #=> 8 (5+3 =
ANSI编码
a = “我是个中文abc”
puts a.size #=> 13 (5X2+3 = 13)
puts a.split(//e).length #=> 8 (5+3 =
=======================
4) empty? ruby中字符串提供了empty?方法判断是否为空。注意,如果有空格或者tab,都不算为空的。
=======================
a = “”
p a.empty? #=> true
a = ” ”
p a.empty? #=> false
=======================
5) split和unpack。 ruby中分割字符串有两种方法,一种是split,按特定字符分隔,另一种是unpack,按“字节”数分隔。unpack的参数格式是aXaX,“X”表示要截取的字节数。需要注意提,如果X+X的字符数不够整个字符串长度的话,字符串后面的字符就没了,如果超过总长度的话,会按最大数来截取,如果不确定最后一节的长度,可以使用a*来截取至结尾处的部分。
=======================
a = “1:2:3:4:5:6″
p a.split(“:”) #=>["1","2","3","4","5","6"]
p a.unpack(“a2a3″) #=>["1:","2:3"]
p a.unpack(“a2a30″) #=>["1:","2:3:4:5:6"]
p a.unpack(“a2a3a*”) #=>["1:","2:3","4:5:6"]
=======================
6) +,<<,和concat。 ruby中字符串的连接有三个方式。用+号可以新建一个字符串,用<<和concat可以修改原字串的值(不新建字符串)。因为<<和concat是修改址的方法,影响会比较大,切忌不要乱用。
=======================
a = “123″
b = “456″
p a + b #=> “123456″
p a #=> “123″
a = “123″
b = “456″
a << b
p a #=> “123″
a = “123″
b = “456″
a.concat(b)
p a #=> “123456″
=======================
7) chomp! 。 删除行尾换行符。 以gets等方法从标准输入读入字符串时,行尾会接着换行符,但实际在处理字符串时,换行符经常很碍事,因此,加上chomp!几乎是一种固定写法。
=======================
a = “123\n”
p a.size #=>4
a.chomp!
p a.size #=>3
while line = gets
line.chomp!
..
end
=======================
8) chop和chop!。 用于删除字符串的最后一个字符。

Array 类
1)新建数组。 ruby中新建数组有多种方法。
<1> 使用[],类似于js。
================================
a = [1,2,3]
p a #=> [1,2,3]
================================
<2> 使用Array.new。
================================
a = Array.new
p a #=> []
a = Array.new(5)
p a #=> [nil,nil,nil,nil,nil]
a = Array.new(5,0)
p a #=> [0,0,0,0,0]
================================
<3> 使用%w。 %w方法很奇怪,后面接的可以直接是字符串,而不必带”号。通常情况下,可以选用()做为参数的边界符,如果字符串本身包含()这样的字符,为免造成影响,还可以使用<> || !! @@ AA这样的来做边界符。%w方法会以空格为分隔,将字符拆分成数组。
================================
a = %w(abc 123 def 456 ghi)
p a #=> ["abc","123","def","456","ghi"]
a = %w<(abc) 1(23 g()h>
p a #=> ["(abc)",“1(23”,"g()h"]
================================
<4>其它对象的to_a方法。 比如说hash对象就可以通过to_a转换成数组。
================================
h = {“name” => “adang”,”sex” => “male”}
a = h.to_a
p a #=>[["name","adang"],["sex","male"]]
================================
<5>字符串的split方法。
================================
s = “ab-123-cd-45″
a = s.split(“-”)
p a #=>["ab","123","cd","45"]
================================
2) 数组的索引。
<1> a[n]
这个用法和别的语言没啥区别,唯一奇怪的是n可以为负值,表示倒数。另外,a.slice(n)和a.at(n)效果和a[n]相同。
================================
a = ["a","b","c","d"]
p a[0] #=> a
p a[-2] #=> c
p a.slice(-2) #=> c
p a.at(-2) #=> c
================================
<2> a[n..m]
会将a[n]到a[m]之间的范围建立出新的数组返回。a.slice(n..m)和a[n..m]效果相同。
================================
a = ["a","b","c","d"]
p a[1..3] #=> ["b","c","d"]
p a[1..6] #=> ["b","c","d"]
p a.slice(1..3) #=> ["b","c","d"]
p a[a] #=> ["a","b","c","d"]
================================
<3> a[n,len]
从a[n]处开始获取len个元素,建立新数组并返回。a.slice(n,len)和a[n,len]效果相同。
================================
a = ["a","b","c","d"]
p a[1,2] #=>["b","c"]
p a[1,6] #=>["b","c","d"]
p a.slice(1,2) #=>["b","c"]
p a #=>["a","b","c","d"]
================================
<4> a.values_at(n1,n2,…)
a[n..m],a[n,len]方法新建的数组都只能是连续位置上元素,a.values_at方法可以返回不连续的索引组成的新数组。
================================
a = ["a","b","c","d"]
p a.values_at(1,3,0) #=> ["b","d","a"]
p a #=> ["a","b","c",“d”]
================================
3) 改写数组。a[n],a[n..m],a[n,len]不仅可以读数据,还能写数据。注a.at,at.slice方法都只能读,不能写,只有a[]可以写。
================================
a = ["a","b","c","d","e","f","g"]
a[1..3] = ["B","C","D"]
a[4,2] = [1,2]
p a #=> ["a","B","C","D",1,2,"g"]
================================
4) 插入元素。 ruby中插入数据原理和js里一样。js中是通过splice方法先删几个元素,再添几个元素,ruby中也是如此。
================================
a = ["a","b","c"]
a[2,0] = [1,2]
p a #=> ["a","b",1,2,"c"]
a = ["a","b",“c”]
a[1,1] = [1,2,3]
p a #=> ["a",1,2,3,"b","c"]
a = ["a","b","c"]
a[1..2] = [1,2,3]
p a #=> ["a",1,2,3]
================================
5) 交集、并集和差集。 ruby中数组还可以进行交集和并集的计算,分别使用 & 和 | 作为运算符。
================================
a = ["a","b","c","d"]
b = ["b","e","a"]
p a & b #=> ["a","b"]
p a | b #=> ["a","b","c",“d”,"e"]
p a #=> ["a","b","c","d"]
================================
对数组直接使用 + – 运算符,可以分别得到数组连接的效果和差集的效果。
================================
a = ["a","b","c","d"]
b = ["b","e","a"]
p a – b #=> ["c","d"] (a有,但b没有的元素)
p a + b #=> ["a","b","c","d","b","e","a"] (a和b简单地叠加)
p a | b #=> ["a","b","c","d","e"] (a和b的并集,重复元素去除)
================================
6)数组的队列性。 和js一样,ruby中的数据也有push,pop,unshift,shift方法,此外a << 赞同于a.push。
================================
a = ["a","b","c"]
a.unshift(1)
a << 2
a.push(3)
p a #=> [1,"a","b","c",2,3]
p a.shift #=> 1
p a #=> [“a”,"b","c",2,3]
p a.pop #=> 3
p a #=> ["a","b","c",2]
================================
7) a.concat和 + 。 在js中数组是不能直接相加的,如果需要组合两个数组,是用a.concat(b)来实现的,但js中a.concat(b)是会返回一个新数组的,还可以利用这一点轻松复制一个复杂类型的数组。但ruby中concat是具有破坏性的,会影响到a。如果想不影响到a,可以使用+号。
================================
a = ["a","b","c"]
b = [1,2,3]
c = a + b
p c #=>["a","b","c",1,2,3]
p a #=>["a","b","c"]
c = a.concat(b)
p c #=>["a","b","c",1,2,3]
p a #=>["a","b","c",1,2,3]
================================
8)a.compact。 a.compact可以从数组中删除nil元素。有compcat和compact!之分。
================================
a = [nil,"a",nil,"b","c",nil]
a.compact!
p a #=> ["a","b","c"]
================================
9)a.uniq。 a.uniq可以删除数组中的重复元素。有a.uniq和a.uniq!之分。
================================
a = [1,2,3,4,3,2,1]
a.uniq!
p a #=> [1,2,3,4]
================================
10) a.delete(x)、a.delete_at(n)、a.delete_if{|item| …}
a.delete(x)可以直接从数组中删除指定元素(为啥js中没有这么好用的方法?T_T )。
a.delete_at(n)删除指定索引的元素(js的splice方法去死吧 T_T)。
a.delete_if{|item| …} 遍历数组元素,如果区块返回结果为真,则删除。 (for循环去死吧 T_T)。
================================
a = [1,2,3,2,4,nil]
a.delete(2)
p a #=> [1,3,4,nil]
a = [1,2,3,2,4,nil]
a.delete_at(2)
p a #=> [1,2,2,4,nil]
a = [1,2,3,2,4,nil]
a.delete_if{|item| item > 2 if item}
p a #=> [1,2,2,nil]
================================
11) a.slice!()。 前面说过a.slice的效果等同于a[],包括a.slice(n),a.slice(n..m),a.slice(n,len)。slice方法还有slice!的形式,slice!方法的返回值相同,但会从数组中删除掉返回值。
================================
a = [1,2,3,4,5,6]
p a.slice!(1) #=> 2
p a #=> [1,3,4,5,6]
p a.slice!(2..3) #=> [4,5]
p a #=> [1,3,6]
p a.slice!(1,1) #=> [3]
p a #=> [1,6]
================================
12) a.collect和a.map。 如果需要让数组中所有元素统一变化,再也不用for()去循环,再赋值这么麻烦了,a.collect和a.map都可以返回让数组中的值进行处理之后,将返回的结果组成新数组。a.collect和a.map效果相同,且都有!的形式。
================================
a = [1,2,3]
a.collect!{|item| item * 2}
p a #=> [2,4,6]
a.map!{|item| item * 3}
p a #=> [6,12,18]
================================
13) a.fill。 a.fill可以将数组a的元素改写为指定的参数。但我a[n..m]=和a[n,len]=不同的是,a.fill只能将指定范围内的元素修改成一种参数(只有一种)。a.fill有a.fill(value),a.fill(value,begin),a.fill(value,begin,end),a.fill(value,n..m)几种不同的方式。
================================
a = [1,2,3,4,5,6]
a.fill(8)
p a #=> [8,8,8,8,8,8]
a = [1,2,3,4,5,6]
a.fill(8,3)
p a #=> [1,2,3,8,8,8]
a = [1,2,3,4,5,6]
a.fill(8,3,2)
p a #=> [1,2,3,8,8,6]
a = [1,2,3,4,5,6]
a.fill(8,2..4)
p a #=> [1,2,8,8,8,6]
================================
14)a.flatten。 将数组扁平化,多层数组可以变成一个单层的数组。有a.flatten和a.flatten!之分.
================================
a = [1,[2,3],[[4,5],6,[7,[8,9]]]]
a.flatten!
p a #=> [1,2,3,4,5,6,7,8,9]
================================
15)a.reverse。 逆转数组,有a.reverse和a.reverse!之分。
================================
a = [1,2,3]
a.reverse!
p a #=> [3,2,1]
================================
16)sort和sort_by。 sort对数组排序,对应的还有sort!方法。另外ruby还提供sort_by方法,sort_by返回新数组,没有对应的sort_by!
=================================
a = [2,4,3,5,1]
a.sort!
p a #=> [1,2,3,4,5]
b = a.sort_by{|i| -i}
p b #=> [5,4,3,2,1]
p a #=> [1,2,3,4,5]
=================================
17) each和each_width_index。 数组遍历最常用的做法是使用each方法,但each方法只会返回一个返回值,只有元素,没有索引,如果需要索引的话,可以使用each_with_index方法。
=================================
a = [1,2,3]
a.each{|i| print i,”\n”}
a.each_with_index{|i,n| print n,” : “,i,”\n”}
=================================

Numeric类
1) 整型和整型相加结果为整形,整形和浮点型相加,结果为浮点型。
================================
p 1+1 #=>2
p 1+1.0 #=>2.0
p 3 * 2.0 #=>6.0
================================
2) divmod。 除了+ – * / %之外,ruby中数值类型还有divmod方法,它也是除的运算符,只是返回值是数组的形式,第一项是商,第二项是余数。
================================
p 16.divmod(5) #=> [3,1]
================================
3) Math模块和round方法。 ruby提供了Math模块,但和一般语言不同的是,round、ceil和floor方法并不是从属于Math模块的,而是直接绑定在数值类上的。Math模块提供的方法有sin、cos、tan、asin、acos、atan、exp、log、log10和sqrt。数值类型的对象转换可以用 to_f、to_i方法。浮点型转整型会直接去掉小数点后的值。字符串调to_i方法相当于js中的parseInt方法。
================================
f = 4
p Math.sqrt(f) #=> 2
include Math
p sqrt(f) #=> 2
p 10.to_f #=> 10.0
p 10.8.to_i #=> 10
p “123″.to_i #=> 123
p “123abc”.to_i #=> 123
p “abc123″.to_i #=> 0 (不是nil哦)
p 1.2.round #=> 1
p 1.2.floor #=> 1
p 1.2.ceil #=> 2
================================
3) 循环。 数值类型可以直接用来循环。
================================
ary = []
3.times{|i| ary << i}
p ary #=>[0,1,2]
ary = []
2.upto(5){|i| ary << i}
p ary #=>[2,3,4,5]
ary = []
5.downto(2){|i| ary << i}
p ary #=>[5,4,3,2]
ary = []
10.step(20,3){|i| ary << i}
p ary #=>[10,13,16,19]
10.step(2,-3){|i| ary << i}
p ary #=>[10,7,4]
================================

1) sleep方法。 ruby中也有定时器,sleep相当于js中的setTimeout函数,不同的是sleep后的参数单位是秒,不是微秒。
2)ruby的函数中return是可以省略的,如果省略,方法中的最后一个语句的计算值会是返回值。
========================================
def area(x,y,z)
xy = x * y
yz = y * z
zx = z * x
(xy + yz +zx) * 2
end
p area(2,3,4) #=>52
========================================
3) 判断对象的类型。 ruby有个和js中判断对象类型相近的方法,instance_of?。除了instance_of?之外,ruby的对象还有个很好用的方法,叫class,通过class方法可以直接得到对象的类型,需要注意的是.class返回的不是字符串,而是类。
========================================
str = “abc”
arr = [1,2,3]
p str.class #=> String
p arr.class #=> Array
p str.instance_of?(String) #=> true
p arr.instance_of?(Array) #=> true
p str.class == String #=> true
========================================
和js一样,ruby中所有的类都继承自Object。但和js不一样的是,js的instanceof可以一直往上追踪,但ruby不行,ruby为往上追踪提供了另外一个方法is_a?。例如
=========================================
js:
var arr = [1,2,3];
alert(arr instanceof Array); //true
alert(arr instanceof Object); //true
ruby:
arr = [1,2,3]
p arr.instance_of?(Array) #=> true
p arr.instance_of?(Object) #=> false
p arr.is_a?(Object) #=> true
==========================================
4) ruby中的常量真是容易定义,用大写字母开头的就是常量了。常量在修改值的时候会报警告。
5)类名。和js不一样的是,js中是出于习惯,提倡类名首字母大写,并没有做硬性要求。ruby的类名却强制性要求首字母大写。原因是ruby要求类名必须为常量。
6)构造函数。ruby的构造函数并不是和类名同名的方法,而是统一使用initialize方法。一般语言都可以设定构造函数的访问性,设计模式中的单独模式就是通过构造函数的访问性做的文章。as3中强制构造函数为public,而ruby强制构造函数为private。
7) 实例化。 ruby的实例化一个类,不是通过new 类名()这种通用方式,而是通过类名.new()。奇怪的ruby语法@_@。
8) 属性的访问性。 和java一样,ruby并不支持直接访问类中的属性,如果要访问类中的属性,需要先通过attr_reader:属性名(只读),attr_writer:属性名(只写),attr_accessor:属性名(读写)来设定属性的访问权限。ruby中没有var关键字,不能通过函数产生变量的作用域。在js里,我们可以在类中定义一个私有变量,在所有的方法中调用。私有变量只要定义为和方法在同一级别,那么它就可以在各个方法中负责通信。ruby中不能使用这种方法,ruby在类里没办法定义变量,只能在方法中定义变量。方法和方法之间如果想通信只能通过@变量,也就是实例变量进行通信。@变量就像是js中的this.xxx变量一样,但js中的this.xxx只能是public的,可读可写,ruby通过attr_xxxx可以控制@变量的访问性。
9)方法的访问性。方法的访问性是通过public,private和protected进行限制的。和一般语言将访问性关键字放在方法前面不同的是,ruby的访问性是通过public :方法名1,方法名2。。。这样的方式进行声明的。属性的访问性可以放在前面,但方法的访问性要放在方法之后,如果放在方法前面会出现方法未定义的报错。除了初始化方法恒化private,其它方法缺省为public。
10)类方法(静态方法)。 ruby中定义类方法有三种方法。
=========================================
1)
class HelloWorld
def HelloWorld.hello(name)
print name,” said Hello.”
end
end
HelloWorld.hello(“John”)
2)
class HelloWorld
..
end
class << HelloWorld
def hello(name)
print name,” said Hello.”
end
end
HelloWorld.hello(“John”)
3)
class HelloWorld
def self.hello(name)
print name,” said Hello.”
end
end
HelloWorld.hello(“John”)
=========================================
需要注意的是,类方法不能访问实例变量。
11)类变量(静态变量)。ruby中类变量是通过加@@标识的。
12)类常量。类中还可以定义常量,还是要求大写字母开头。类中不能定义和方法平缓的变量,但是可以定义和方法平级的常量,常量可以被所有方法调用。类常量的调用方法是类名::常量名。
13)继承。 ruby中的继承不是使用extend关键字,它更简洁,使用<就可以了。ruby也只支持单继承。
14) 类的示例。
========================================
class Dog
attr_accessor:name
def initialize(name = “wang cai”)
@name = name
end
def call
print “I’m a dog , my name is “, @name ,”\n”,Version,”\n”
end
def self.move(num=0)
print “Dog had moved “,num,” bu\n”
print Version,”\n”
end
Version = “1.0″
public :call
end
a = Dog.new
a.name = “huan huan”
a.call
Dog.move(5)
class BigDog < Dog
def call
print “I’m a big dog , my name is “, @name,”\n”
end
end
b = BigDog.new(“abc”);
b.call
print Dog::Version
========================================
15)模块。模块是ruby特有的功能之一。模块和类很像,但和类最大的不同在于模块不能实例化,也不能继承。模块的作用有两个,一个是用于提供命名空间。第二提供Mix-in功能。Mix-in和继承很像,但它不是继承,在《javascript设计模式》一书里,将Min-in称为掺元继承,YUI提供的augment方法,思路就是Mix-in。模块是通过include关键字读入的,它和as中的with()方法有相似的地方,include了文件之后,前辍就可以不用写了。
16)模块的常量和类常用调用方法一样。模块名::常量名。模块的方法调用和类的方法调用不同,可以使用模块::方法名,也可以使用模块.方法名。
17)模块定义的方法默认是不对外部公开的,(模块内没有public private protect关键字),要将方法对模块外部公开,必须使用module_function。
===================================
module HelloModule
Version = “1.0″
def hello(name)
print “Hello, “,name,”.\n”
end
module_function : hello
end
p HelloModule::Version #=>”1.0″
HelloModule::hello(“Alice”) #=> hello, Alice.
include HelloModule
p Version #=>”1.0″
hello(“Alice”) #=>Hello, Alice
===================================

1)ruby的语句可以换行。这一点和js不同,js中换行视作一行语句结束,相当于在句尾加了“;”号,如果一条语句换行写,会报错。ruby中语句可以换行,而且为了提高可读性,bury鼓励不使用“;”号,希望一行语句只写在一行里,可以的话,不要在同一行里写多条语句。
2)ruby中if,while等语句都不带{}号,相反,一些方法例如each则会带{},习惯了C系的语法,看着还真不习惯。总之因为不带{},所以在写if等语句时,一定要注意缩进,不然程序没法看了。
3)ruby中空格不能随便乱加,如果要加空格让程序好看一点,一定要注意讲求平衡。例如:
==============================
a+b
a + b 的效果相同
a +b 效果却等同于 a(+b),a()方法传入+b作为参数
==============================
4) to_i 方法。字符串转换成数字类型。相当于js中的parseInt()。
5) 布尔型转换。 在ruby中,布尔型也是为true和false,同其它语言一样,其它类型的值也能和布尔型进行隐式转换。但和大多数语言不同的是,在ruby中,false和nil以外所有的对象都为真,false和nil为假。包括0,在ruby中其实都是相当于真,这点和一般的语言不大一样。另外,ruby是个支持谓语的语言,鼓励返回布尔型数据的方法命名时加上“?”,这么做也是为了提高可读性。例如 isNumber? isGood?
6) 条件判断。 在ruby中,条件判断有一点很奇怪的是else if的写法,既不是“else if”也不是“elseif”,是“elsif”,汗,为啥把那个e给省掉了?看着多别扭啊。。。
============================
a = ARGV[0]
b = ARGV[1]
if a > b then
print “a > b”
elsif a == b then
print “a = b”
else
print “a < b"
end
============================
除了if,ruby中还提供了unless方法,语法和if一样,但和if正相反的是,unless中的条件不成立时,才会执行。
7) case语句。 ruby 中的case语句相当于其它语言中常用的switch,但ruby中的格式奇怪一点,功能也更强一点:
=============================
=begin
这是一般的用法
=end
tags = ["A","IMG","PRE"]
tags.each{ | tagname |
case tagname
when "P","A","I","B" then #bury这里可以写多个参数,用逗号隔开
print tagname,"has child.\n"
when "IMG","BR" then
print tagname,"has no child.\n"
else
print tagname,"cannot be used.\n"
end
}
=begin
when 里还可以放 String,Numberic之类的类型名,判断类型
=end
array = ["aa",1,nil]
item = array[0]
case item
when String
puts "item is a String."
when Numberic
puts "item is a Numeric."
else
puts "item is a something."
end
=begin
when 里还可以放正则表达式
=end
case line
when /^From:/i
print "找到寄件人了。\n"
when /^To:/i
print "找到收件人了。\n"
else
print "啥也没找到。"
end
=============================
需要注意的是,ruby中的when后面的条件不会自动转换类型,比如说1和"1"是不一样的。另外,很重要的一点是,when后面的语句不需要加break,这和C系的switch是不一样的。
8) ===。ruby中也有===号,但它和js中的===并不相同,ruby中的===左边可以是数字、字符串,也可以是正则,还可以是类型。
=============================
p (2 === 2) #=> true
p /zz/ === “zyzzy” #=> 2
p String === “xyzzy” #=>true
=============================

1) ruby的函数在调用的时候可以加括号,也可以不加括号。
函数定义的格式也比较奇怪:
==============================
def hello
print(“Hello World”)
end
hello()
==============================
2) ruby的输出方法有print,puts,p和pp。其中print是普通输出,它接受多个参数,在输出的时候会把所有参数拼起来然后输出;puts和print类似,不同的地方在于puts会在输出之后自动加上换行,如果传了多个参数,那个每个参数后都会自动加上换行;p和pp设计的目的都是为给程序员调试用的,它们输出的信息能包含更多信息,例如字符串在输出的时候会加上引号,pp和p不同的地方在于pp输出时会自动加入缩进和换行,让数据显示时的可读性更好。
3)单引号和双引号。和php一样,单引号中不能包含变量,双引号中可以包含变量。在ruby中,单引号中的\n这样表示换行之类的转义字符都会无效,直接输出出来。
4)注释。 ruby中的注释和c系语言不同,不是使用//和/**/,取而代之的是#和=begin,=end。
=============================
=begin
我是一个多行注释哦,
我换行了,
我又换行了
=end
# 我是一个单行注释
=============================
5) if判断。 也和C系不同,看起来更像是vb的语法。没有{}这样明显的分隔,如果不加上缩进的话,可读性该有多差啊@_@
=============================
if a >= 10 then
print(“big”)
else
print(“small”)
end
==============================
6) 循环。使用while:
==============================
i = 1
while i <= 10
print(i,"\n")
i = i + 1
end
==============================
使用times方法。当循环次数确定时,使用times方法会更简单:
==============================
100.times {|i|
print "hello ",i,"\n"
}
100.times do |i|
print "hello",i,"\n"
end
==============================
使用for。ruby的for有两种用法,一种是类似于C系的for(var i=0;i
==============================
sum = 0
for i in 2..5
sum += i
end
print sum
==============================
另一种类似于js的for(var p in Obj){}:
==============================
names = ["a","b","c"]
for name in names
print name,"\n"
end
==============================
和js的for (p in obj)不同的是,这里的p不是索引。例如上面代码的输出不是0,1,2,而是"a","b","c"。
如果换成是hash,又会怎么样呢?
==============================
names = {"a" => 1,”b” => 2,”c” => 3}
for name in names
print name,”\n”
end
==============================
输出是什么呢?a1,b2,c3,直接将键和值拼起来一块儿输出了。
ruby 的退出循环也比较奇怪。break和C系一样,C系的continue在ruby中叫next。注意,exit是退出整个程序,不是退出循环。
7) 迭代。 其实迭代也是我们熟悉的循环中的一种。和C第语言不同的是,对于复杂数据类型,比如数组,我们使用的不是for(var i=0,n=arr.leng;i
===============================
#数组
name = ["a","b","c"]
name.each{| n |
print n,"\n"
}
#hash
a = {"name" => “adang” , “sex” => “male”}
a.each{| key , value |
print key , ” : ” , value , “\n”
}
===============================
hash。 ruby也支持hash数据。和js不同的是,js的hash格式是{name1 : value1 , name2 : value2},而ruby的hash格式不是用:分隔,而是=>,这种使用习惯更像php。在调用hash数据时,js可以通过hash[name],或者hash.name的方式调用,而ruby只能通过hash[name]调用。
==============================
a = {“name” => “adang”,”sex” => “male”}
print a["name"]
==============================
9) 数组。 ruby的数组和js没太大区别,也可以通过 a = [] 来快速定义一个数组,有点奇怪的是ruby中数组长度不是通过arr.length来获得的,而是通过arr.size,这里size不是属性而是方法。
10) 正则。 和js一样,ruby的正则也可以通过/abc/的形式创建,但它的匹配方法和js不同,js中最常用的匹配方法是test,/abc/.test(str)是最常用的方式。在ruby中,匹配是通过 =~ 运算符来实现的,如果匹配成功,返回索引值,如果匹配失败,返回空值nil。nil应该相当于js中的null了:
==============================
p /Ruby/ =~ “Ruby” #=> 0
p /Ruby/ =~ “Diamond” #=> nil
==============================
11) ARGV数组。 这个数组是用来保存命令行对指令脚本传入的实参,类似于js中的augments数组。
12)读取文件。 读取文件的方式和php有点像,也是先打开文件,然后读取内容,最后关闭文件。
==============================
#整篇读取
filename = ARGV[0]
file = open(filename)
text = file.read
print text
file.close
#结合正则表达式,逐行读取 (我怎么看着这么像读取数据库中的数据的形式呢?)
pattern = Regexp.new(ARGV[0])
filename = ARGV[1]
file = open(filename)
while text = file.gets do
if pattern =~ text
print text
end
end
file.close
==============================
13) 将输出保存到文件中。 ruby比起js可以做更多的事了,比如说,读取或输出文本到文件,在ruby中将输出结果存在文件里非常简单,执行程序的时候,在指令的后面加上 “>文件名”,则输出就会被存在文件里。
==============================
> ruby test.rb > test.html
==============================
14) require。 像大多数语言一样(js除外),ruby支持require,需要被require的文件只需要被 require “fileName“就可以被包含进来了,值得注意的是,fileName可以省掉”.rb”后辍。
15) 全局变量和局部变量。 js的全局变量和局部变量是通过var关键字结合函数作用域实现的,在ruby中,是通过$符号来区别全局变量和局部变量的。比如说a.rb和b.rb同时都定义了$str和str两个变量,a.rb里require了b.rb文件,那么b.rb中的$str会影响到a.rb文件,因为他们是同一个变量,而b.rb中的str不会影响到a.rb中的str。
16)==,eql和equal。 在ruby中所有的对象都持有身份标识(ID),它是ruby原生支持的。这让我想起YUI了,YUI中也会自动对对象生成ID作为身份标识,不仅是DOM对象,也包括程序中的对象,这点和ruby异曲同工,只是ruby原生就支持,通过object_id可以获得。
==============================
ary1 = []
p ary1.object_id #=> 67653636
==============================
判断两个给定的对象是不是同一对象(ID相同),可以通过equal?方法来进行判断。
==============================
str1 = “foo”
str2 = str1
str3 = “f” + ”o“ + “o”
p str1.equal?(str2) #=> true
p str1.equal?(str3) #=> false
==============================
在这里有个概念需要清楚,在ruby中,一切数据都是对象,”foo”在这里是作为一个对象存在的,这点和as3一样,str2 = str1这一步的时候,其实不是复制了一份”foo”字符传给了str2,而是直接将str1的址传给了str2,此时str1和str2指向的是同一个内存地址,这么设计的目的当然是为了节约内存。equal?()比较的应该是内存地址是否一致,而不是“值”是否一致。在js中,传值还是传址,是根据数据类型决定的,赋值时无法指定,string,num等等基本类型是传值,array,hash等复杂类型是传址。php里传值还是传址是通过有无&符号决定的,有&传址,无&传值。ruby里只会传址,不会传值。但和as3一样,虽然是传址,但其实它不是普通的传址,而是传的一种“不变对象”,当“不变对象”的值被改动的时,其实并不是改变“不变对象”本身,而是新生成一个不变对象,而将旧的不变对象由垃圾回收机制自动回收。关于这一点,可以参考黑羽的《action script3殿堂之路》第21页“基元数据类型的深入讨论”。
前面说的是“址”的比较,对于“值”的比较,ruby提供了==和eql方法,==和eql之间的关系就相当于js中的==和===关系。
==============================
p 1.0 == 1 #=> true
p 1.0 eql?1 #=> false
==============================
