1. 标准类型
1.1 数字
Ruby支持整数和浮点数。整数可以是任何长度,一定范围内的整数在内部以二进制形式存储,它们是Fixnum类的对象,范围之外的整数存储在Bugnum类的对象中。Ruby会自动管理它们之间的来回转换。
在书写整数时,可以使用一个可选的前导符号,可选的进制指示符(0b表示二进制,0表示八进制,0d表示十进制,0x表示十六进制),后面跟一趾符合适当进制的数字,下划线在数字串中被忽略。
带有小数点或幂的的数字字面量被转换成浮点对象,必须在小数点之前和之后都给出数字,比如"1.0e3"写成"1.e3",Ruby会试图调用Fixnum类的e3方法。
整数也支持几种迭代器,比如times表示次数,例如:
6.times {puts '-'}
还有upto和downto,它们在两个整数之间分别向上和向下迭代,例如:
1.upto(10) {|i| puts i} 10.downto(1) {|i| puts i}
Numeric类提供了更通用的step方法,例如:
1.step(100, 10) {|i| puts i}
1.2 字符串
Ruby字符串是8比特字节的序列,通常它们包含可打印字符,但这不是一个必要条件,字符串也可以包含二进制数据,字符串是String类的对象。
可以在字符串字面量中放置各种转义序列,例如"\n",表示一个回车换行符。除此之外,可以使用"#{}"序列把任何Ruby代码的值放进字符串中,如果代码只是全局变量、类变量或实例变量,花括号可以忽略。
另外还有3种方式去构建字符串字面量。"%q"和"%Q"分别开始界定单引号和双引号的字符串,例如:
%q/Hello World!/ %Q/Hello #{name}/
跟在q或Q后面的字符是分界符,字符串被一直读取直到发现相匹配的结束符号,否则,字符串会被一直读取,直到出现下一个相同的分界符。
最后,可以使用"here document"构建字符串,例如:
string = <"here document"由源文件中的那些行但没有包含在"<<"字符后面指明终结字符串的行组成,如果把一个减号放在"<<"字符后面,就可以缩进编排终结符,例如:
string = <<-END_OF_STRING Hello World! Hello John! END_OF_STRINGRuby有75个以上的标准方法,比如String#chmop方法可以去除首尾空格,例如:
puts "Hello World!\r\n".chompString#split方法可以根据正则表达式分割字符串,例如:
stringlist = 'Hello John!'.split(/ /) puts stringlist[1]String#squeeze方法可以删除重复字符,例如:
puts 'Hello World!!!'.squeeze('!')String#scan方法从字符串中抽取匹配正则表达式的元素,例如:
puts 'Hello World!'.scan(/e.*l/)
1.3 区间
区间的第一个且可能最自然的用法是表达序列,在Ruby中使用".."和"..."区间操作符来创建序列。两个点的形式是创建闭合的区间,而3个点的形式是创建半闭半并的区间(不包括右端的值)。可以使用to_a方法把区间转换成数组,例如:
(1..10).to_a ('bar'..'bat').to_a区间实现了许多方法可以迭代它们,并且以多种方式测试它们的内容,例如:
digits = 0..9 digits.include?(5) digits.min digits.max digits.reject {|i| i<5} digits.each {|digit| dial(digit)}Ruby可以根据自己所定义的对象来创建区间,唯一的限制是这些对象必须返回在序列中的下一个对象作为对succ的响应,而且这些对象必须是可以使用"<=>"来比较的,"<=>"操作符比较两个值,并根据第一个值是否小于、等于或大于第二个值,分别返回-1,0或+1,例如:
class Test include Comparable attr :value def initialize(value) @value = value end def <=>(other) self.value <=> other.value end def succ Test.new(@value.succ) end end myvalue = Test.new(1)..Test.new(9) myvalue.to_a myvalue.include?(Test.new(2))区间可以当作条件表达式来使用,当区间第一部分的条件为true时,它们就打开,当区间第二部分的条件为true时,它们就关闭,例如:
while line = gets puts line if line =~ /start/ .. line =~ /end/ end区间还有一种用法是间隔测试,看一些值是否会落入区间表达的间隔内,使用"==="操作符即可,例如:
(1..10) === 5
1.4 正则表达式
正则表达式被用来根据模式对字符串进行匹配。Ruby提供了内建的支持,使得匹配和替换更方便和更简明。正则表达式是Regexp类型的对象,可以通过显示调用构造函数或使用字面量形式"/pattern/"和"%r{pattern}"来创建它们,例如:
Regexp.new('^[a-z]+') /^[a-z]+/ %r{^[a-z]+}有了正则表达式对象,可以使用Regexp#match或匹配操作符"=~"和"!~"对字符串进行匹配。匹配操作符对String和Regexp对象均有定义,例如:
name = 'John' name =~ /o/ /a/ =~ name匹配操作符返回匹配发生的字符位置,它们会设置一些Ruby变量。"$&"得到与模式匹配的那部分字符串,"$`"得到匹配之前的那部分字符串,而"$'"得到匹配之后的那部分字符串。
每个正则表达式包含一种模式,用来对字符串进行正则表达式的匹配。在特殊字符之前放置一个反斜线便可以匹配它们的字面量。
2. 方法
2.1 定义方法
可以使用关键字def来定义一个方法。方法名必须以一个小写字母开头。表示查询的方法名通常以"?"结尾,例如instance_of?。会修改接收者对象的方法,可以用"!"结尾,例如chop和chop!,第一个方法返回一个修改后的字符串,而第二个则就地修改对象。可以被赋值的方法以一个等号"="结尾。
方法可能还需要声明某些参数,它们就是括号中列出的局部变量。方法参数两边的括号是可选的,例如:
def method1(arg1, arg2, arg3) end def method2 endRuby可以指定方法参数的默认值,例如:
def method(arg='John') end如果希望传入可变个数的参数或者用一个形参接收多个参数,在参数名前放置一个星号"*"即可,例如:
def method(*arg) end当调用一个方法时,可以用一个block与之相关联,通常可以使用yield从方法内部调用这个block。但是如果方法定义的最后一个参数前缀为"&",那么所关联的block会被转换为一个Proc对象,然后赋值给这个参数,例如:
def method(&block) block.call() end method() {puts "Hello World!"}
2.2 调用方法
可以通过指定接收者、方法的名称、可选的参数及block,来调用一个方法。对类方法或模块方法来说,接收者是类或模块的名字。如果省略了接收者,其默认是self。 每个被调用的方法都会返回一个值。Ruby有一个return语句,可以从当前执行的方法中退出,如果不需要return,则返回的是方法执行中最后一个语句执行的结果。
在方法定义中,如果在一个正规参数前加上星号,那么传入这个方法调用的多个参数将会被装入一个数组。如果要分解一个数组,则在数组参数前加一个星号"*",例如:
def method(args1, args2, args3) puts "#{args1} #{args2} #{args3}" end method(1, 2, 3) method(1, *[2, 3])