1、The Declarative Programming Language : Ruby,范玉雷 中国人民大学WAMDM实验室 http:/,1、Ruby发展历史 2、Ruby优缺点 3、编程环境介绍 4、字符串、正则表达式、数组和哈希 5、控制结构 6、类、对象、方法和变量 7、异常处理 8、模块,发展历史,Ruby是一种解释型的方便快捷的面向对象脚本语言,并且是一种具有函数式及指令程序设计特性的新语言。由日本的Yukihiro Matsumoto于1993年2月24日首次发布的。 Ruby版本发展历史: 1995 12月-Ruby 0.95版本 1996 12月-发布Ruby 1.0版本 1
2、997 8月-发布Ruby 1.1版本 1998 12月-发布了安定版1.2和开发版1.3 2007 3月-发布了稳定版本1.8.6 最新版本:1.8.7(2008年) JRuby:类似Python的Jython,一个可于Java上执行Ruby的语言,支持Java的接口和类别。最新发布版为0.8.1(2005-04-11),与Ruby 1.8.2兼容。,Ruby优缺点,Ruby是面向对象的编程语言,追求“简便快捷的面向对象编程”。Ruby是解释型语言,不需编译即可快捷地编程。同时Ruby具有类似Perl的强大的文本处理功能。此外,还可以很方便地使用C语言来扩展Ruby的功能,因此可以把它当作各
3、种库的前端来使用。 缺点:因为Ruby是解释型语言,所以速度较慢,静态检查比较少。,优点: 解释性脚本语言 有直接呼叫系统调用的能力、强大的字符串操作和正则表达式 迅速和简便 无需变量声明、变量无类型、语法简单而坚实、自动内存管理 面向对象编程 任何事物都是一个对象、类、模块糅合、迭代器 多精度整数 数值可以为很大 异常处理模式 类似其他面向对象编程语言的异常处理机制 动态装载 线程,编程环境,在浏览器上试用:http:/ Ruby1.8.6: fxri - Interactive Ruby Help & Console控制台 SciTE文件编写,后缀名为“rb”,字符串、正则表达式、数组和哈
4、希,单引号 escape using “ escape using “ Thats right Thats right 双引号 “Seconds/day: #24*60*60“ Seconds/day: 86400 “#Ho! *3Merry Christmas!“ Ho! Ho! Ho! Merry Christmas! “This is line #$.“ This is line 3 puts “now is # def the(a) the + a end the(time) for all good coders.“now is the time for all good coder
5、s.,三种构建字符串字面值方法: %q/general singlequoted string/ %Q!general doublequoted string! general doublequoted string %QSeconds/day: #24*60*60 Seconds/day: 86400 string = END_OF_STRINGThe body of the stringis the input lines up toone ending with the sametext that followed the END_OF_STRING,正则表达式是类型Regexp的对象。
6、它们可以显式地用构造函数或使用字符值形式/pattern/ 和%rpattern来创建。 a = Regexp.new(s*az) /s*az/ b = /s*az/ /s*az/ c = %rs*az /s*az/ 使用Regexp#match(string) 或者用匹配操作符=(确定匹配)及 !(否定匹配)。 name = “Fats Waller“ name = /a/ 1 name = /z/ nil /a/ = name 1,a = 1, cat, 3.14 使用w%代替复杂的声明方式 a = %w ant bee cat dog elk a = ant, bee, cat, dog
7、, elk 可以通过=进行赋值 b = Array.new #直接创建Array对象。 b.class Array b.length 0 b0 = “second“ b1 = “array“ b “second“, “array“,用一对数字start, count来对数组进行索引。 a1, 2 cat, 3.14 使用Range对象或Range字面值来对数组进行索引:范围用“”和“”表示 a02 1, cat a02 1, cat,3.14 如果在 =操作符中下标索引为两个数字或者一个Range字面值,则原始数组内对应的一系列值将被替换为操作符右边的值。 a = 1, 3, 5, 7, 9
8、1, 3, 5, 7, 9 a2, 2 = cat 1, 3, “cat“, 9 a2, 0 = dog 1, 3, “dog“, “cat“, 9 a1, 1 = 9, 8, 7 1, 9, 8, 7, “dog“, “cat“, 9 a03 = “dog“, “cat“, 9 a56 = 99, 98 “dog“, “cat“, 9, nil, nil, 99, 98,哈希表:由key和value组成 h = dog = canine, cat = feline, donkey = asinine h.length 3 hdog “canine“ hcow = bovine h12 = d
9、odecine hcat = 99 h “cow“=“bovine“, “cat“=99, 12=“dodecine“,“donkey“=“asinine“, “dog“=“canine“,块:使用定义 或者使用begin/doend定义 简单的迭代: 1, 3, 5,7,9 .each |i| puts i 1 3 5 7 9 “H“, “A“, “L“.collect |x| x.succ “I“, “B“, “M“ 自定义迭代: def three_timesyieldyieldyieldendthree_times puts “Hello“ ,控制结构,Case语句 case abcd
10、ef when aaa, bbb print “aaa or bbbn“ when /def/ print “includes /def/n“ end 使用了字符串相等和正则表达式匹配,还可以使用的有数值相等、数值是否在规定范围内等。可以用来赋值。 leap = casewhen year % 400 = 0: truewhen year % 100 = 0: falseelse year % 4 = 0end,if语句 puts “Danger, Will Robinson“ if radiation 3000 if radiation 3000puts “Danger, Will Robi
11、nson“end if elsif elseend if song.artist = “Gillespie“ then handle = “Dizzy“elsif song.artist = “Parker“ then handle = “Bird“else handle = “unknown“end 可使用冒号:来替换then,使代码更简洁些。使用表达式进行赋值 handle = if song.artist = “Gillespie“ then “Dizzy“elsif song.artist = “Parker“ the“Bird“else“unknown“end,Unless语句 un
12、less song.duration 180 cost = 0.25elsecost = 0.35endcost = song.duration 180 ? 0.35 : 0.25,While语句 while weight 100 and num_pallets = 30pallet = next_pallet()weight += pallet.weightnum_pallets += 1end 两种等价形式的while语句 square = 2 while square 1000square = square*squareend square = square*square while s
13、quare 1000,Until语句 until play_list.duration 60 play_list.add(song_list.pop)end Until语句的简单表示法 a -=10 until a 100,循环迭代器 for song in songlistsong.play end songlist.each do |song| #等价形式song.play end,Break、Redo、 Next和Retry break 立即结束当前循环;然后跳出去执行循环后面的语句。 redo从这次循环体的头开始重新执行,但是不会在对条件进行运算或者从迭代中取下一个值。 next跳到本
14、次循环末尾,开始执行下一次循环while line = getsnext if line = /s*#/break if line = /END/ redo if line.gsub!(/(.*?)/) eval($1) end Retry语句就是个入场卷。它重新开始任何的迭代循环。for i in 1100print “Now at #i. Restart? “retry if gets = /y/end,类、对象、方法、变量,类 class end 对象 “gin joint“.length 9 “Rick“.index(“c“) 2 -1942.abs 1942 方法 defend,类
15、class Songdef initialize(name, artist, duration)name = nameartist = artistduration = durationenddef to_s “Song: #name-#artist (#duration)“ end end song = Song.new(“Bicylops“, “Fleck“, 260) song.inspect #缺省地,inspect消息,可以被发送给任何对象,格式化对象的ID和它的实例变量。 ,继承 class KaraokeSong Songdef initialize(name, artist,
16、duration, lyrics)super(name, artist, duration)lyrics = lyricsend end aSong = KaraokeSong.new(“My Way“, “Sinatra“, 225, “And now, the.“) aSong.to_s “Song: My Way-Sinatra (225)“,重载方法to_s class KaraokeSong def to_s “KS: #name-#artist (#duration) #lyrics“ end end aSong = KaraokeSong.new(“My Way“, “Sinat
17、ra“, 225, “And now, the.“) aSong.to_s “KS: My Way-Sinatra (225) And now, the.“ 使用父类方法进行修改:super + “ #lyrics“,类的属性存取控制器 class Song attr_reader :name, :artist, :duration end aSong = Song.new(“Bicylops“, “Fleck“, 260) aSong.artist “Fleck“ aSong.name “Bicylops“ aSong.duration 260 其他访问方式关键字:attr_writer,a
18、ttr_accessor,虚拟属性 class Songdef duration_in_minutes #可以看作和其他一样的属性。duration/60.0enddef duration_in_minutes=(new_duration)duration = (new_duration*60).to_iendend song = Song.new(“Bicylops“, “Fleck“, 260) song.duration_in_minutes 4.33333333333333 song.duration_in_minutes = 4.2 song.duration 252,类变量 cla
19、ss Songplays = 0 #使用前必须被初始化。def initialize(name, artist, duration)name = nameartist = artistduration = durationplays = 0enddef playplays += 1 plays += 1“This song: #plays plays. Total #plays plays.“endend s1 = Song.new(“Song1“, “Artist1“, 234) s2 = Song.new(“Song2“, “Artist2“, 345) s1.play “This son
20、g: 1 plays. Total 1 plays.“ s2.play “This song: 1 plays. Total 2 plays.“ s1.play “This song: 2 plays. Total 3 plays. “,类方法 class SongListMAX_TIME = 5*60 # 5 minutesdef SongList.is_too_long(song)return song.duration MAX_TIMEendend song1 = Song.new(“Bicylops“, “Fleck“, 260) SongList.is_too_long(song1)
21、 false song2 = Song.new(“The Calling“, “Santana“, 468) SongList.is_too_long(song2) true,单例(Singletons) class MyLoggerprivate_class_method :newlogger = nildef MyLogger.createlogger = new unless loggerloggerendend MyLogger.create.id 936550 MyLogger.create.id 936550 通过标记 MyLogger类的new方法为私有属性,我们可以防止任何人使
22、用常规构造器创建一个logger对象。要想使用这个log类,只有一种创建方法:Logger.create,并且确保系统中只有一个log的实例存在。,访问控制权限: protected 、private和public class Accountattr_reader :balanceprotected :balanceend class MyClassdef end # default is publicprotected # 后面方法将是 protecteddef end # will be protectedprivate # 后面方法将是 privatedef end # will be
23、privatepublic # subsequent methods will be publicdef end # and this will be publicend class MyClassdef end # . and so onpublic :method1, :method4protected :method2private :method3end,变量Variables person1 = “Tim“ person1.id 936870 person1.class String person1 “Tim“ 一个变量只是指向一个对象的引用 person2 = person1 pe
24、rson10 = J person1 “Jim“ person2 “Jim“ 用String的dup方法,创建一个新的字符串对象 person2 = person1.dup person10 = “J“ person2 “Tim“ 冻结(freezing)对象不想别人修改一个对象 person1.freeze,可修改的类的属性attr_writer class Songdef duration=(new_duration)duration = new_durationend end 两个值互换: a, b = b, a 并行赋值: name, block = name, block 嵌套赋值:
25、 b, (c, d), e = 1,2,3,4 #= b = 1, c = 2, d = nil, e = 3 b, (c, d), e = 1,2,3,4 #= b = 1, c = 2, d = nil, e = 3,异常处理,结构 Begin #开始# Rescue #可以使多个,用来捕获异常,并对异常对象进行操作# Else #只有在不引发异常的时候才执行的代码# Ensure #无论是否发生异常都会执行的代码# End #结束 在一个rescue子句中使用retry语句来重新进入到begin/end块中。,主动引发异常-raise方法 raise #简单地重新引发当前异常 raise
26、 “bad mp3 encoding“ #创建一个新的RuntimeError异常,用指定字符串设定它的消息。 raise InterfaceException, “Keyboard failure”, caller #第一个参数创建一个异常,然后用第二个参数设置相关消息和堆栈轨迹给第三个参数。堆栈轨迹通常使用Kernel.caller方法来产生。 给异常添加信息 class RetryException RuntimeErrorattr :ok_to_retrydef initialize(ok_to_retry)ok_to_retry = ok_to_retryend end,Catch
27、和 Throw-catch定义带有给定名字(可以Symbol或String)标签的块。块通常会被执行直到它遇见throw。 catch (:done) dowhile line = getsthrow :done unless fields = line.split(/t/)songlist.add(Song.new(*fields)endsonglist.play end,模块,模块类似于类: 模块不可以有实体 模块不可以有子类 模块由module.end定义. 举例模块定义了一个命名空间 module TrigPI = 3.141592654def Trig.sin(x)enddef Tr
28、ig.cos(x)end end y = Trig.sin(Trig:PI/4),混合插入-实现了多重继承。 module Debugdef who_am_i?“#self.class.name (#self.id): #self.to_s“end end class Phonographinclude Debug end class EightTrackinclude Debug end ph = Phonograph.new(“West End Blues“) et = EightTrack.new(“Surrealistic Pillow“) ph.who_am_i? “Phonograph (#935520): West End Blues“ et.who_am_i? “EightTrack (#935500): Surrealistic Pillow“,Thank You!,