Ruby初探

来源:互联网 发布:windows属于系统软件 编辑:程序博客网 时间:2024/04/24 18:35

入职后的第一个项目决定采用ROR开发。听说ROR的大名已经很长时间了,正好借此机会系统学习一番。要系统学习一项新的技术,我习惯先从宏观上了解它的特点、起源、发展过程、当前的状况这些常识性的内容。这些常识性内容看起来就像看故事,比较轻松,算是一个热身,主要关注两个方面:第一就是这些常识性知识,这也许是将来和别人交流的铺垫;第二就是了解这种技术中提倡的一些原则和方法论上的东西,这些是精髓,很多的技术细节都是围绕这些原则设计和实现的,对于深入理解技术细节是很有帮助的。

RORRuby的很多资料都是从网上搜集的,包括很多的电子书。学习ROR首先要学习Ruby语言,了解Ruby的前世今生。网上的一份较早的Ruby入门资料(张开川著)短小精炼,我觉得作为初步了解Ruby是很合适的,总结一些有助于学习和理解Ruby的内容于此,不过多涉及语法。

计算机编程语言的发展总是与飞速发展的世界息息相关,Ruby是为了适应变化,提高和完善编程艺术而出现的。Ruby是一种动态脚本语言,汇集了许多其他语言的特性,例如Perl的正则表达式、Python的简单性可读性、Smalltalk的纯面向对象语法和单继承、Lisp的无穷嵌套的语法、Java的线程。编程语言将向动态回归,命令式语将与函数式语言融合。终究有一天,编程语言完全智能化,人们用自然语言来编程。而Ruby有可能在编程语言的智能化发展道路上起到承上启下的作用(张开川)。Ruby灵巧、快速,但其实并不简单。Ruby中实现一个小功能,可以有3种甚至4种完全不同的思路与方法,因为Ruby在语法层次实现了冗余,但是这样一来:1)程序员深入掌握 Ruby变得不很容易;2)程序员们相互读懂代码也很难;3)软件生产是一种大规模地、群体合作的行为,而Ruby 灵巧,快速,千变万化,没有统一风格,难于解耦,不适合工业生产。(目前业界很多公司和组织都在积极实践Ruby应用于大规模的软件开发)。

学习编程的过程,就是深化理解变量的过程。先说变量是什么?变量是代号。在数学中,你写下一个小写的英文字母“f”,这个f 可以是数字5,也可以一个函数式f = n * n + 1,还可以是一个曲面,或者是一个逻辑蕴涵关系。编程语言的产生,建立在数学的基础上。在汇编语言的时代,一条语句”LD  x, 37H”,其中LD是操作码,代表一种操作;x37H是操作数,是被操作的对象。无论是LD,还是x37H,对于机器来说,都只是符号。后来,编程语言发展成两大类,一类是函数式语言,一类是命令式语言。命令式语言将操作数演化成现在我们熟悉的变量,将操作码演化成方法(或叫函数),对变量执行各种操作。面向对象编程又将基本变量和方法封装在一起,成为一个更复杂的变量——对象。但是,在一个类中仍然区分基本变量和方法。函数式语言则不同,一开始的函数式语言不区分变量和方法,一切都是表(list),表就是能够不断分解成单个元素的数学符号。表可以是变量,可以是方法。后来的有些函数式语言,吸取了命令式语言的语法,也区分变量和方法。也有一些命令式语言,融合了函数式语言的语法,Ruby就是这样的语言,变量和方法区分得不很明显。

其次,说一说变量有哪些特征呢?

1)变量有名字;

2)变量代表的那个事物应该有一个可以用数学度量的值:长度,面积,速度,大小,磁场强度…

3)为了区别事物,我们将事物分成几个基本类型。所以,为了代表不同类型的事物,变量也就有了不同的类型。

4)事物总是有产生到消亡的一个过程,因此,代表事物的变量也就有了生命周期。计算机科学,是一门将时间转换成空间的科学。在程序中,我们把变量的生命周期,称之为变量的作用域。

变量名,变量值,变量类型,变量的作用域,是学习命令式语言不可回避几个要素。

如果你是一门编程语言的设计者,仔细考虑一下,上面四个要素,对于编程语的使用者都是必须的吗?作为一个使用者,1)2)是必须的。至于类型、生命期,与我何干?某个变量,我使用一下就丢弃了,要我操心太多,还不如我从头设计呢。由编译内核(或解释内核)在运行时刻来判断变量类型的语言,叫动态类型语言。

变量既然是代号,那么可以代表数字、文字(字符串)、代码序列(块、闭包)、一段程序(文件)……在运行中,变量能够随时代表不同的事物,而不管事物是什么类型,这种语言,叫弱类型语言。这里的“弱”,是指弱化了类型的概念,不理会类型的差异。

Ruby语言还是有基本类型的。至于变量作用域,纯粹的函数式语言中是没有这个概念的。Ruby中是有变量作用域概念的。Ruby语言中,一切都是对象,变量是不是对象呢?变量不是对象,变量只是引用某个对象的时候,你看到的一个代号而已。

Ruby是动态类型语言,不用给任何变量指定数据类型,解释器会在你第一次赋值给变量时,在内部将数据类型记录下来。Ruby语言中,一个变量被赋予了某个数据类型的值,在程序中你可以随时再予这个变量其它数据类型的值。相对于Java Ruby对于变量的使用给予了用户很大的自由。在Java中,编程的时候就完成了类型匹配的检测,这属于前期绑定;Ruby是在运行中检测,检测类型匹配吗?不是检测类型匹配,而是检测语法,只要与语法定义不矛盾就通过。Ruby是动态语言,可以改变Ruby程序的结构、功能,在Ruby程序运行中,方法、属性可以被加入或去除,新的类或对象可以被建立,新的模块可以出现。Ruby的动态类型特点是一把双刃剑,熟手游刃有余,生手常常伤着自己。在没有了编译器查错的日子里,又没有完全驾驭Ruby之前,如何避免常常出错呢?一种办法就是死盯住变量的命名。用一些有意义的名字,不必太长,但是应该少用单字符,除非是循环指针变量。你也许认为自己能看懂就行了,这是十分有害的想法。在一个项目组中,程序员是要彼此相互沟通合作的。当坏习养成后,要改是很难的。

Ruby语言只有重写(override),没有其它语言具有的严格意义上的重载(overload)。下面仔细分析Ruby为何没有重载,只有重写。Java的重载,参数列表有三种不同形式:1)参数个数不同;2)参数个数相同,参数类型不同;3)参数个数相同,参数类型相同,对应位置不同。Ruby支持缺省参数,支持可变参数。由于缺省参数和可变参数,参数个数不同而产生的重载,在 Ruby中不再有效。Ruby 语言中,定义方法时,不指定参数类型,因此第二种形式的重载也不存在。第三种形式的重载,实际是第二种形式的演化,所以,也就不存在了。综上所述,Ruby语言没有方法的重载。如果在同一个类中写两个同名方法呢?总是写在后面的方法被执行。Java C++是静态语言,程序代码运行中不可以再改变类的属性、方法,为了更好地表现面向对象的多态特征,所以用重写和重载来加强程序的灵活性,在程序运行的时候,动态地选择要使用的方法,完成后期绑定。而Ruby是动态语言,可以随时改变类的属性、方法,所以重写和重载的重要性就降低了。

Ruby里,可以给具体的实例对象添加实例方法,把这样的方法称之为单例方法。定义单例方法,首先要生成一个实例对象,其次,要在方法名前加上对象名和一个点号“.”。  实例方法,属于类的每个实例对象。单例方法只出现在单个实例对象中。用单例方法可以极大地丰富多态性在 Ruby中的表现力。

Ruby里有一个很重要的单元是模块。一般把功能相关的程序代码放在一个模块里。模块与类非常相似,但是模块不可以有实例对象,模块之间不存在继承关系。模块的作用有三:1)可以被其它程序代码重复使用;2)提供了一个命名空间,防止命名冲突;3)实现了类似多重继承的功能。通过“<  父类名 ”,一个子类可以得到父类的属性和方法;通过“include 模块名”,一个子类可以得到某个模块的常量和方法。类不能被 include include方法为一个类的所有对象包含某个模块;extend方法为一个类的某对象包含某个模块。

使用 require 方法让你的程序文件变得简洁有力。require方法包含另一个文件,另一个文件名需要是一个字符串。还有一个load方法与require方法相对应,也用来包含另一个文件。require包含的文件只加载一次,遇到同一文件时自动忽略;不同路径下的同文件会多次加载。load包含的文件加载多次,即使是相同路径下的同一文件。利用load多次加载文件的特性,可以用来实现程序的无缝升级和系统的热部署。程序功能改变了,你只需要重新load 一次,其它代码与它再次交互的时候,实际上已经不是原来的程序了。require 加载文件时可以不加后缀名,load 加载文件时必须加后缀名。require 一般情况下用于加载库文件,而 load 用于加载配置文件。

 

 

原创粉丝点击