[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'