
Ruby 基础
作者:Ralf Wirdemann, Thomas Baustert
2006.2.14
1.1 在线文档和书籍
语言资料上,如果要找核心和标准API的文档可以去 www.ruby-lang.org,深步进阶我们推荐下面的书籍:
Dave Thomas: Programming Ruby, Second Edition, Pragmatic
Bookshelf, 2005
Ruby书籍中的标准著作,极具推荐价值。
Hal Fulton: The Ruby Way, Sams, 2001
这部书不仅仅有Ruby语言的最新状况,还提供了一百个案例,很有意思。
1.2 引言
Ruby 是一个纯粹的面向对象的动态型语言。Ruby
程序不是被编译成二进制格式(如Java),而是直接由一个解释器来处理。这门语言在1995年由松本行弘(Matsumoto
Yukihiro)发布,除了 Smalltalk、Python 等语言以外,Perl
对它的影响是首当其冲的。
Ruby
里的一切都是对象,它没有原始类型(如Java)。除了面对对象,Ruby还提供了垃圾回收、异常、正则表达式,为迭代器和方法作参数的“代码块”,运行期的类扩展,线程及更多的东西。Ruby
语言易懂易用,原因在于它简单、语法干净。
1.3 Ruby 程序
Ruby 程序保存在以 .rb 结尾的文件里。程序内容包含类、模块、或者只是简单的Ruby代码。下面是地球人都知道的 Hello World 程序:
#
hello.rb
puts "Hello
World!"
如果这个代码是以 hello.rb 的文件名保存的,那么可以这样调用:
> ruby
hello.rb
> Hello
World!
在Windows下允许您以文件关联的方式在IE中执行;在 Linux/Unix 下您可按照自已的操作系统情况使用 Shebang行:
#!/usr/local/bin/ruby
puts "Hello
World!"
#!/usr/bin/env
ruby
puts "Hello
World!"
随后直接执行这个程序:
> chmod 744
hello.rb
>
./hello.rb
Ruby 的语句可以以分号结尾,但不是必须。 Ruby 是一个面向行的语言,也就是说,一个语句不需要以分号结尾,解释器能够明白下一行是进一步的语句。下面前几个语句的输出相同,最后一个是错误的:
puts "Hello
World!";
puts "Hello
World!"
puts "Hello "
\
"World!";
puts "Hello"
+
"World!";
puts "Hello" #
语句至此结束
+ "World!"; # 无法被解释的新语句
多个语句可以用分号隔开写到一行里面,这不是很地道的写法,因为会影响阅读的流畅。
#
可行,但不漂亮:
a = 42; b = 15; c = a +
b
#这样比较好:
a =
42
b =
15
c = a +
b
Ruby 以两个空格作为缩进的方式(不用Tab键),这是个推荐习惯并且应该尽可能地得到遵循:
#
非常棒的缩进
while line =
file.readline
if
!comment_line(line)
lines.add(line)
end
end
# oh~,oh~,您这是和外星人学的吧
while line =
file.readline
if
!comment_line(line)
lines.add(line)
end
end
Ruby
提供了全系列的标准类型,如数字、字符串、正则表达式、数组、哈希(Hash),等等。所有这些元素通过类和模块的方式以备使用,无需在程序(文件)中绑定,它们来自于核心库并在整个程序中自动生效。
另外一些是以其它类和模块构成系列的标准库方式以备使用的,例如
Date、Logger、Test::Unit
等等。一旦要自行开发就必须在每个程序里通过关键字 require
来明确绑定。于是在 require 后加上或有或无结尾(.rb)的文件名。
require "date" # date.rb 用到
Date类
require "my_class" # my_class.rb
用到MyClass类
require "my_module" # my_module.rb 用到 MyModule模块
对此处文件名的处理不是按绝对路径,Ruby 会在所有的标准目录下寻找这个文件,它们被包含在全局变量$: 里面,您可以在命令行用 ruby -e "puts $:" 或其它方式得到这些路径。一个装载了类和模块的程序里的所有名字都可以通过全局变量 $" 输出。
1.4 注释
在 Ruby 中注释行是以#号开始的,注释可出现在句首或句尾。
#
下面这行是被注释掉的
# a = b -
c
a = b + c #
注释到行尾
一个注释块开始于 =begin 结束于 =end,这几个关键字必须在行首,不能有空格。
=begin
def
my_method
...
end
=end
1.5 数字
Ruby支持整数和浮点数。Ruby 里面没有原始类型,都是数字对象。整数从负2的30次幂到正2的30次幂 (在64位机器上从负2的62次幂到正2的62次幂) 被定义成FixNum类型 超出此范围的整数被定义成BigNum类型,类型的划归与转换是自动完成的,一个数字的长度最终由主存来判定。
value = 42 #
FixNum
big_value = 123456789012345678901234567890 # BigNum
数字可以用16进制、8进制或者2进制的数字系统来表示:
#
42
0x2A
0052
b101010
有相应的数学运算符以供使用,数字的增减用运算符 += 与 -= 来实现, 出自 C 和 Java 的 ++ 与 -- 在 Ruby 里是没有的。
a =
2
b =
3
c = a + b #
5
c = a - b #
-1
c = a / b #
0
c = 2.0 / b # 0.666666666666667
c = a * b #
6
c = a**b # 2*2*2 =
8
a += 1 # a =
3
a -= 1 # a =
2
a++ #
Ruby里非法
FixNum与BigNum 继承于基类 Integer,以下是可用的函数,是与块(见1.14节)结合的:
1.upto(3) { [i] puts i } # 1 2
3
3.downto(3) { [i] puts i } # 3 2
1
0.step(10,2) { [i] puts i } # 0 2 4 6 8
10
3.times { puts *42* } # 42 42
42
浮点数在 Ruby 里是用 Float 类来表示的。像其它语言一样,Ruby 里的浮点也有卷折误差。为了计算精确(如 合值),建议使用 Ruby 标准库里的 BigDecimal 类,相对于 Float,这个类描述了更为丰富的浮点数并且避开了卷折误差。
1.6 字符串
在 Ruby
里,字符串被放置在两个单引号或双引号之间。引号常会出现在另一个引号里面:
str = "Hello"
# Hello
str = "Hello 'Thomas'" # Hello 'Thomas'
str =
'Hello' #
Hello
str = 'Hello "Thomas"' # Hello "Thomas"
字符串可以通过 %q 和 %Q
产生,这是为了避免当一个字符串内出现过多的引号或其它符号时会出现这样或那样的错误。%q
产生一个被包含在单引号中的字符串,%Q
产生一个被包含在双引号中的字符串,文本以分隔符为界来限定,分隔符可以是除字母与数字以外的所有符号。
%q{a string}
%q(a string)
%Q$a string$
%Q 可以替换
#{Ausdruck}这样的表达式,而%q不能:
表格1.1 字符串中带双引号的逃脱符 \a 响铃
\b 退格
\e 逃脱
\f 换页
\n 换行
\r 回车 \s 空格
\t Tab
\v 垂直表格跳位
\nnn 八进制
\xnn 十六进制
\cx Control-x \C-x Control-x
\M-x Meta-x
\M-\C-x Meta-Control-x
\x x
#{code} code
puts %q{result: #{42.0/3} EUR} # result:
#{42.0/3} EUR
puts %Q{result: #{42.0/3} EUR} # result:
14.0 EUR
在花括号、圆括号、角括号的情况下字符串是括号括起来的部分,其它则是到那个符号再次出现为止。字符串也可多行显示,Ruby
在此并不清除起始空格符。
s = %Q@ein String ber
mehrere
Zeile mit "" und '' und durch
einen Klammeraffen begrenzt@
puts s
=>
ein String ber mehrere
Zeile mit "" und '' und durch
einen Klammeraffen begrenzt
puts s.inspect
=>
"ein String \374ber mehrere\n Zeile mit \"\" und '' ...
...und durch \n einen Klammeraffen begrenzt"
一个表达式的结果可以通过#{Ausdruck}插入到一个字符串中,然而这只有在双引号之间有效。
"Ergebnis #{42*7/100} %" #
Ergebnis #{2.94} %
"Die Anwort ist:
#{answer(x)}"
# Die Anwort ist: 42
如C与Java所惯用的,特殊符号由斜杠逃脱,表1.1列举了所有的特殊符号:
"Ein Slash:
\\"
# Ein Slash: \
"Er rief:
\"Ralf!\"" # Er
rief: "Ralf!"
'War\'s
okey?'
# War\'s okey?
"Neue\nZeile"
# Neue
#Zeile
'Neue\nZeile'
# Neue\nZeile
两个字符串的内容可以用 ==
方法来比较,与之相对照的是 equal?
,它用来判断是否是同一个字符串实例(参看1.15.5节):
s1 = "Thomas"
s2 = "Thomas"
s3 = "Ralf"
s1 == s2 # => true
s1 == s3 # => false
s1.equal? s1 => true
s1.equal? s2 => false
s1.equal? s3 => false
字符串可以用+和<<这两个方法连接。使用 *
可实现多重累加。
"Thomas" + "/Ralf" # Thomas/Ralf
s = "Thomas"
s << " und Ralf" # Thomas und
Ralf
"Ralf " *
2 #
Ralf Ralf
字符串类提供了大量的方法,让你随心所欲,下面是几个例子;
s = "Thomas und Ralf"
s[3]
# 109
s[3].chr
# m
s[7,3]
# und
s[0..6]
# Thomas
"Thomas und
Ralf".delete("a") #
Thoms und Rlf
"Thomas und Ralf".delete("aou")
# Thms nd Rlf
"Thomas und Ralf".gsub("und", "oder") # Thomas oder Ralf
"Thomas und Ralf".gsub(/[aou]/, "$") # Th$m$s $nd R$lf
"Thomas und
Ralf".index('a')
# 4
"Thomas und
Ralf".index('a',5) #
12
"Thomas und
Ralf".split
# ["Thomas", "und", "Ralf"]
为字符串转换成整数和浮点数提供两种途径,安全一些的是使用核心方法
Integer 和 Float, 它们在出错的时候抛出异常; 另一种是 String
类的方法 to_i 和 to_f,限制较少 。
"42".to_i
# => 42
nil.to_i
# => 0
"42x".to_i
# => 42
Integer("42") # =>
42
Integer(nil) #
=> 0
Integer("42x") # =>
参数错误
Powered by Haiwit