早已是大师的Martin,现场与观众一起体验了Ruby编程。
现场演示Ruby编程
我们现场有多少人使用过ruby进行开发?很惊讶,只是个别人。所以很多人还没有见过ruby,这就是我带笔记本来的原因了。我将演示一下我们究竟能用ruby做什么。这样的话,我们将会对这个语言有一个认识。我现在把话筒放在一边,放好我的笔记本电脑。
Ruby是一种立即执行的脚本语言。接下来在编辑器环境中新建一个源代码文件。
这个控制台的窗口不会被经常用到,不用担心,我可以键入这个文件的名称,然后运行它。我同样可以在编辑器里做这件事情,把它打印在其他的文件里面。我们现在要做一个小程序。这里是一些数据图表,把它想象成是每个国家的图表,包括:失败图表(fails figures),执行图表(operating figures)等等。这些可能是业务人员每天要关注的事情。现在我们把第一项想象成地区,第二项想象成预期的销售额,第三项,想象成实际情况。那么现在这些业务人员提出了一个要求,让我打印出这些数据,并且显示出预期值与真实值之间差别的百分比。所以我们需要花一些时间完成这个工作。
我们要做的第一项工作是读出这个文件,并且把它显示出来。我在一开始会比较慢的展示应该怎样做。(输入代码)这会是一个比较简单的版本。它现在能够把文件的内容显示出来了。我下面来解释一个这里的语法。这里有一个File类,有个方法是open。在这里并没有在参数外面加上括号,不过如果需要的话可以在这里加上,程序依然能工作。括号在ruby编程中是可以选择的,这看起来不是一个很重要的语法点,但是很多时候,这是非常重要的,比如在接下来的编码中,或者是其他的一些脚本。之后这里有一个非常简单的while循环。我们结果一个局部变量line. 同过getline得到这个变量。记住,只有在需要的时候才去声明这个变量,我们不预先声明。之后我们输出这一行,然后关闭文件。
但是,我已经说了,这不是用ruby实现这个功能的方式。通常,你会这样做。这里出了一个错误。Ruby有一个非常好的帮助系统。我们在这里察看一下错误究竟出在哪里。我确实记不起来了。不过可以看一看以前写过的。这样的编程是非常危险的,因为你需要知道你在做什么,同时要把你正在做的东西表达出来。这是非常难的,我很少这样做。所以这里,我正在做的这个事情,就这个语言来说是非常老练的(sophisticated)。这里对于文件的每一行进行了操作。这一部分是文件的closure. 这里是说,在do和end之间执行这一段非常短的代码。在每次执行命令的时候,都执行一次。把一段代码作为参数传入一个function,这在编程语言中是非常常见的。在smalltalk中是如此,那么在java中的也是,匿名方法(anonymous method)。C#中的代理从根本上来说也是这个道理。closure是ruby的一个特点非常强大的特点。如果你经常使用ruby的话,你会发现,这种closure有非常非常多的应用。在这里使用这种方式的好处是,它可以对你传入文件名的每一个文件的每一行执行这个操作,在执行完之后会关闭文件。如果不用这种方法,你必须要每次执行完操作就关闭文件,这就形成了一系列的事务,在做完一件事情的时候要去做下一件。使用这种匿名方法的方式就可以避免这个问题。
接下来要做的事情是,把这一行输出放入一个对象里。在这里建立一个类,名字是performance. 现在给这个类建立我们需要的figure, 名字是attr_assessor, 然后定义name amount 和actual, 这里实际上定义了我们需要显示的三个值。这里我就可以对我的循环里的代码进行改变了。
P = performance.new
p.name = line.split(‘,’)[0] 这里行可以用逗号分隔,然后我们得到其中的第一个。之后我们输出p,这里我们看到输出的是p这个对象本身,而不是我们希望的值。在java中,我们可以定义一个字符串类型。但是在ruby里面,我们定义一个def to_s函数, 使它返回name的值。现在,我们在输出结果里面,就看到我们真正想要的name了。所以,我们可以看到,建立一个我们需要的类是非常容易的。接下来,我们可以把这个类改为真正的面向对象风格。我们需要结果返回一个数组。Read方法的是返回result这个数组。(进行了一系列代码的动作,调试,忘记把p加入到result数组中了)这样就得到了正确的结果。我们有一些值需要放入我们的这个类里。通过这样做,我们就可以实现了。这里line.split(‘,’)会返回一个数组。这一句代码执行了复合的操作。每一个变量,对应到数组中的不同的值。这是脚本语言的一个特点。所以,在返回字符串的函数里加上plan,加上actual. 再次查看结果,我们就可以看到我们想得到的所有值了。
现在来看我们的代码是很有条理的。那么我们可以加入计算的功能了。定义一个variance方法。返回(actual -plan)/plan * 100,这样我们就得到了百分比。(写了一系列代码)这时候我可以确定代码是不能运行的,因为现在这些值都还是字符类型(写了一系列代码)。所有的脚本语言都有一个共同的问题:没有异常机制的。但是可以通过其他方式处理错误。现在来看一看结果,我得到了极限值。这里是因为我忘了加入浮点。这样的话结果就是正确的了。不过,我们得到的输出是很难看的。我们即将使用Ruby的格式化字符串的机制。(写了一些代码使输出变为小数点后一位。)接下来输出国家名,这样我们就可以看到完整的显示了。在格式化字符串输出的这段代码里面,就像C语言里面一样,可以对输出进行格式化。
现在程序还是有一些问题,不过我们要继续看下一部分了。在perfs加入排序。这里通过variance进行排序。(写了一些代码)现在显示的结果是按照variance进行排序的了。我们需要知道的最重要的是这一行代码。这是ruby中closure的使用。我把数组放在raw_perfs里,它按照特殊的域进行了排序,然后对他进行了另一个操作。在集合上进行了操作的叠加。在ruby里,对collection的这种操作,使ruby成为一个非常简洁的语言。无论是对smalltalk还是对list,对对象这样的操作都是相似的。但是,当你还没有使用这种语言的时候,它看起来并不普遍。但是你一旦开始利用这种特性,它将会变得非常强大,因为你可以方便的使用你的meta进行操作。