[size=x-large]Ruby是面向对象的语言[/size]
在Ruby中,所有的东西都是对象。
创建一个对象通常使用构造函数,一般使用new方法来创建对象
song1 = Song.new("Ruby Tuesday")
song2 = Song.new("Enveloped in Python")
# and so on
[list=1]
[*]所有的对象有一个唯一的对象标识。
[*]你可以定义实例变量,每个对象的实例变量都是独立的。
[/list]
对于每一个类,都可以定义实例方法。可以在类内部或外部(取决于方法的可访问性)访问该实例方法。
有时候我们也把调用对象的方法称为[i]传递消息给方法[/i]。
"gin joint".length » 9
"Rick".index("c") » 2
-1942.abs » 1942
sam.play(aSong) » "duh dum, da dum de dum ..."
值得一提的是,Ruby中有些方法的调用和其他语言不同。例如下面的Java代码:
number = Math.abs(number) // Java code
在Ruby中,代码是这样的:
number = number.abs
对所有的Ruby对象来说都是这样的:在C中,你会使用strlen(name),而在Ruby中则是name.length。
[size=x-large]Some Basic Ruby[/size]
def sayGoodnight(name)
result = "Goodnight, " + name
return result
end
# Time for bed...
puts sayGoodnight("John-Boy")
puts sayGoodnight("Mary-Ellen")
很简单,不需要使用花括号结束代码,每一行放置一条语句。
使用关键字def来定义方法,方法名跟在def后面,这里是sayGoodnight,再后面的括号中的我不用说,大家也知道了,是参数列表,参数列表中的各个参数用逗号分隔,这和c是一样的,不同的是,ruby是弱类型语言,所以不需要像C语言那样限定每个参数的类型。那么参数是什么类型了,答案是object。
注意到,我们没有声明result变量,是我们前面声明了么,不是。记住,ruby是弱类型语言,不需要声明变量,变量在使用它的时候就会自动被创造出来。
``puts sayGoodnight("John-Boy")''这一行有两个方法调用,你发现了么?第一个,也是首先被调用的是sayGoodnight方法,这个学过C的同学一看就明白了,第二个是puts方法,学过C的同学会有些不适应,没关系,ruby是个很灵活的语言,就调用函数而言,你可以使用括号将参数括起来,也可以不用括号,所以下面四个语句的作用是一样的,而且都是合法的。
puts sayGoodnight "John-Boy"
puts sayGoodnight("John-Boy")
puts(sayGoodnight "John-Boy")
puts(sayGoodnight("John-Boy"))
当然,你很快会发现某些情况下不使用括号或造成歧义,那么就使用括号消除歧义好了。
这个例子涉及到了string对象,ruby中的string对象和其他类c语言一样,是放置在引号中的字符串,不过与C和Java不同的是,可以放在双引号中间也可以放在单引号中间。
放在不同的引号中间是有区别的,这里的是新概念了。放在单引号中的字符串Ruby不做任何处理,而放在双引号中间的Ruby会做处理,主要是字符转义和变量解析。
看下面的例子,放在双引号中的"\n"会被转义成回车:
puts "And Goodnight,\nGrandma"
输出是:
produces: And Goodnight,
Grandma
变量解析的意思是将 #{ expression } 解析替换为expression的值。例子:
def sayGoodnight(name)
result = "Goodnight, #{name}"
return result
end
最后,因为ruby的函数会自动将函数最后一行的返回值作为函数的返回值返回(好多返回啊,希望能看明白),所以函数可以简化成这样:
def sayGoodnight(name)
"Goodnight, #{name}"
end
在ruby中,变量的名字和它们的类型是紧密相关的,局部变量就和常见的c变量类似,全局变量前面有$符号,实例变量前面是@,类变量前面是@@,常量的第一个字符是大写(所以类名也是一个常量^_!!)。
变量名和类名的例子
Variables Constants and
Local Global Instance Class Class Names
name $debug @name @@total PI
fishAndChips $CUSTOMER @point_1 @@symtab FeetPerMile
x_axis $_ @X @@N String
thx1138 $plan9 @_ @@x_pos MyClass
_26 $Global @plan9 @@SINGLE Jazz_Song
[size=x-large]Arrays and Hashes[/size]
Ruby中的数组和Hash都是索引容器,不同的是数组是用整数做索引,而Hash用的是对象做索引(当然,通常是用string或symbol)。
数组的创建可以使用下面代码,用方括号括起来,数组中的每个元素的类型可以不同。
a = [ 1, 'cat', 3.14 ] # array with three elements
# access the first element
a[0] » 1
# set the third element
a[2] = nil
# dump out the array
a » [1, "cat", nil]
当然,数组也可以用标准的new方法来创建
empty1 = []
empty2 = Array.new
某些特殊的情况我们要创建字符串数组,那么可以使用以下代码:
a = %w{ ant bee cat dog elk }
a[0] » "ant"
a[3] » "dog"
Hash和数组的明显区别是使用花括号而不是方括号。
instSection = {
'cello' => 'string',
'clarinet' => 'woodwind',
'drum' => 'percussion',
'oboe' => 'woodwind',
'trumpet' => 'brass',
'violin' => 'string'
}
访问Hash中的元素:
instSection['oboe'] » "woodwind"
instSection['cello'] » "string"
instSection['bassoon'] » nil
最后一行显示,如果Hash中不存在键所对应的值时,返回nil,代表空对象,这很好理解。但某些情况我们想改变缺省,可以使用new方法:
histogram = Hash.new(0)
histogram['key1'] » 0
histogram['key1'] = histogram['key1'] + 1
histogram['key1'] » 1
注意到第一行的new方法的参数是0,所以当Hash中不存在键值对时,返回0。
[size=x-large]Control Structures[/size]
Ruby中的if语法:
注意:用end结束if语句
if count > 10
puts "Try again"
elsif tries == 3
puts "You lose"
else
puts "Enter a number"
end
while语句:
while weight < 100 and numPallets <= 30
pallet = nextPallet()
weight += pallet.weight
numPallets += 1
end
下面的if语句很简单:
if radiation > 3000
puts "Danger, Will Robinson"
end
这个语句还可以写成:
puts "Danger, Will Robinson" if radiation > 3000
同样的,下面的while语句:
while square < 1000
square = square*square
end
可以写成:
square = square*square while square < 1000
[size=x-large]Regular Expressions
正则表达式[/size]
下面的正则表达式匹配那些包含Perl或Python的字符串:
/Perl|Python/
两个正斜线中间包含的就是正则表达式。用竖线符号分割的两个部分就是我们要匹配的字符串。还可以用括号将上面的正则表达式写出下面的格式。
/P(erl|ython)/
正则表达式也可以匹配重复的字符。/ab+c/匹配一个以a开始,接着是多个b,然后是一个c的字符串。将加号换成*号,/ab*c/则匹配一个a、0个或多个b、一个c的字符串。
也可以匹配一组字符。\s代表空白字符,\d代表任何数字,\w代表任何可显示的字符,“.”(一个点)代表任何字符。
现在使用上述模式来创建有用的正则表达式。
/\d\d:\d\d:\d\d/ # 时间格式 12:34:56
/Perl.*Python/ # Perl, 0个或多个字符,然后Python
/Perl\s+Python/ # Perl, 一个或多个字符,然后Python
/Ruby (Perl|Python)/ # Ruby, 一个空白, 然后是Perl 或 Python
现在来使用正则表达式。匹配操作符是“=~”,如果在一个字符串中发现了模式,=~返回模式的其实位置,否则返回nil。这就是说可以将正则表达式用作if和while语句的条件。例如,下面的代码片段在字符串包含文本“Perl”或“Python”时显示信息。
if line =~ /Perl|Python/
puts "Scripting language mentioned: #{line}"
end
字符串中匹配正则表达式的部分当然可以被替换为其他文本,使用的替换方法是:
line.sub(/Perl/, 'Ruby') # 替换第一个 'Perl' with 'Ruby'
line.gsub(/Python/, 'Ruby') # 替换所有的 'Python' with 'Ruby'