`
javatoyou
  • 浏览: 1018910 次
  • 性别: Icon_minigender_2
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Ruby系列学习资料(一)

 
阅读更多
值得记忆的是一个新编程语言有时被看作万能药,特别是它的追随者;但是, 没有一个语言能代替所有其他的语言, 没有一个工具对每个任务都是最好的。在世界上有许多不同的问题领域,并且这些领域内有许多可能的限制是可能的。
高于一切,对这些问题有不同的思维方式,源于程序员本身的不同的背景和个性。基于这些原因,不可能预知语言扩散的终点。只要有语言多样性,将会有各样的保护和攻击他们。简而言之,总是存在"语言竞赛"。然而在这本书里,我们不打算参加。
然而,是什么对新的和更好的程序符号有恒久的追求,我们的在困惑,超过它们被创造的思想。正Pascal借用Algol,Java借用C,因此每个语言都从它的前辈借用。语言是工具箱和操场;它有极端实用面,但是它也做为对可以或不可以被计算机界广泛接受的新思想的试验台。
这些思想最广泛延伸的一个是面向对象的编程技术的概念(OOP)。虽然许多会争辩说,OOP 的整体意义演变而不是革命,没人认为,它没有对产业的冲击。二十年前,对象导向很大程度上是学术的好奇心;今天这是一个普遍地被接受的范例。
实际上, OOP 的普遍存在的本质在产业导致了大量相当数量的"炒作"。80年末期,Roger 国王观察,"如果您想要卖猫给计算机学家,您必须告诉他它是面向对象的。" 另外,关于真正地OOP是什么的看法有差异,它们之间本质上同意在术语上有区别。
我们在这儿的目的不是想炒作。我们发现OOP 是一个有用的工具和思考管理问题的方式;但是,我们不宣称它能治疗癌症。
至于OOP 的确切的本质,我们有我们对宠物定义和喜爱的术语,但我们做这些只是为了有效地通信,而不要玩文字游戏。
我们提到这些是因为对OOP 的基本理解是必须的,为了完成本书的大部分和理解例子和技术。对Ruby可能的说法是,它的确是一种面向对象的语言。




一、关于面向对象

在实际谈论Ruby之前,谈谈面向对象程序的概要是个好主意。前面几页将回顾这些概念,并对Ruby语言本身做了粗略的参考。

在面向对象的编程技术中,根本单元是对象,它是做为数据的容器和控制这些数据访问的实体。同对象相联系的是一套属性,它本质上只是属于对象的变量。(在这本书里,我们宽松地给属性使用普通术语变量。) 同样,与对象有联系的还有提供对象的功能接口的一套函数。这些函数被称为方法。
任何OOP 语言本质上都提供封装。作为经常使用的术语,它首先意味, 对象的属性和方法与特定对象关联或者被绑在一起。第二,它意味那些属性和方法的作用域缺省是对象本身(数据隐藏的知名的原则的应用,不是对具体的OOP) 。
对象被认为是一个对象类 (通常简称为类)的一个实例或清单。类可以被视为图纸或样式;对象本身是从那个图纸或样式创建来的。类经常被视为是一种抽象类型,一个更加复杂的类型,比如,整数或字母字符串。
当对象(类的实例) 被创建时,它被说成是实例化。一些语言有明确的构造器和析构器概念,它们是完成任何任务所必须的对象初始化的功能,然后再分别地析构它。我们不妨过早地提一下,Ruby被认为有构造器,但是没有任何析构器概念 (因为它行为良好的垃圾回收机制)。
有时,会出现一个数据片有比单个对象更全局的作用域,并且对于放置属性的拷贝到类的每个实例内是不适当的。例如,考虑称为MyDogs的类,创造它的三个对象:fido,rover,和spot。对每条狗,都有这样的属性如,年龄和种疫苗的日期。但是假设我们想要存放责任人姓名。我们的能可以放入每个对象中,但那是浪费内存和非常不容易理解的设计。owner_name 属性不属于任一个体对象,而属于类本身。当它被定义时(不同语言间句法会有变化),它被称为类属性(或类变量)。
当然, 许多情况下类变量是需要的。例如,假设我们想要保留某些被创建完的类有多少个对象数量。我们可以使用类变量,它被初始化为0并且每个实例会将其增量;类变量同类关联而不是任一特定对象。在作用域内,这个变量就像其它的属性,但对于整个类或从此类创建的所有对象只会有一个拷贝。
为区别类属性和普通属性,后者有时被明确地称为对象属性(或实例属性)。我们将按习惯对任何属性假设为是个实例属性,除非我们明确地称它为类属性。
就像一个对象的方法被用于控制对它的属性的访问并提供一个清晰的接口给他们,所以有时要适当或必要定义同类有联系的方法。类方法,毫不奇怪,控制对类变量的访问并且也同样完成类级别而不仅仅是对象级别的任务。同样数据的属性,方法被假设属于对象而不类,除明确声明。
值得提及的是,有种感觉是所有的方法都是类方法。我们不应该假设当一百个对象被创造时,我们实际上为方法复制代码一百次! 但是,作用域规则保证我们每个对象的方法只在这些方法被调用的对象上操作。
我们现在见识一下面向对象的编程技术中真正强大的一个:继承。继承是个机制,允许我们延伸到先前存在实体,并通过增加特征来创造一个新的实体。简而言之,继承是重复利用代码的途径。
我们典型地认为继承在类级别上。如果我们有具体类在头脑里并且以更一般的情形存在,我们能定义我们的新类来继承旧的那个的特点。例如, 假设我们有类Polygon,它描述凸面多角形。然后如果我们发现自己想要处理Rectangle类,我们可以从Polygon继承,以便Rectangle现在有Polygon有的所有属性和方法。例如,通过重复所有的边并且可增加它们的长度来计算周长方法。假设每件事都被适当地完成,这个方法将会自动地为新类工作; 代码不必被重写。
当类B从类A继承时,我们说B是A的子类,或者说,A是B的超类。这在技术上有些微小的差别,我们可以说A是基类或双亲类,B是导出类或孩子类。
像你已看到的,导出类可以看成对它的基类的方法继承,就像方法是它自己的一样。换句话说,如果必须提供不同的实现的话,它可以重定义先前的方法。另外,大多数语言提供了通过覆写方法来调用双亲类内同名方法的途径。即,如果需要B内的方法foo知道如何从A内调用方法foo。(任何语言提供这个特性则被认为不真正的面向对象的。)本质上说,对于数据属性也这样的。
一个类和它超类之间的关系即有趣也很重要;它通常被认为是"是一个"的关系。因为一个正方形"是一个"矩形,并且一个矩形"是一个"多边形,等等。所以,如果我们创建了一个继承层次(任何OOP语言内存在的一种形式),我们可以看到在层次内的给定点上,更具体的实体"是一个"更通用实体的子类。 注意这种关系类似于前面的例子,你可以很容易地看到,一个正方形"是一个"多边形。也要注意这个关系知道每个矩形是一个多边形,但不每个多边形都是矩形。
这带来了多重继承的问题。可以想像到它是一个新类可以从多于一个的类继承。例如,类Dog和Cat两都可以继承类Mannal,Sparrow和Raven可以从WingedCreature继承。但是我们若想定义类Bat呢?它理所当然地从Mammal和WingedCreature两者继承。这与我们真实生活是很好的对应,这种事情不只是一个类别的成员而是很多非嵌套类别的成员。

多重继承(MI)或许是OOP内最有争议的地方。一种人指出必须解决潜在的二义性。例如,如果Mammal和WingedCreature两都有个属性叫size(或叫eat的方法),当我们从一个Bat对象来引用这个属性时,它们两个哪一个会被引用?另一个相关的困难是"diamond inheritance problem"(这么称呼,是根据它的继承图形状),两个超类继承于一个通用超类。例如,假设Mammal和WingedCreature两者从Organism继承;层次从Organism到Bat形成一个钻石形状。但是两个中间类的属性如何从它们双亲继承?Bat有它们每一个的拷贝或者因为它们来自于同一个祖先而被合并到了一个单独属性中了呢?
这些是给语言设计师准备的而不是程序员。不同的OOP语言有不同的处理方式。一种提出的规则是允许属性的定义成为"win out",或是同名的属性之间差别的方式,或者别名方式或者重命名标识符。This in itself is considered by many to be an argument against MI the mechanisms for dealing with name clashes and the like are not universally agreed upon but are very much language dependent. C++提出了最小特征集来处理二义性;Eiffel或许是最好的,而Perl则与此两者不同。
当然还有一种选择是禁用MI。有些语言接受了如Java和Ruby。这听起来像是妥协;但是,像你稍后看到的,实际上不是那么糟糕。我们将会看到对传递多重继承的一个有效选择,但首先我们必须讨论另一个OOP的专业术语:多态性。
多态性或许是这个领域内最有争议的术语。每个都似乎知道它是什么,但是每个人都有不同的定义。(在近年来,"什么是多态性?"会变成一个大众化问题。如果问到你,我推荐你引用像Bertrand Meyer或Bjarn Stroustrup这样专家的回答;如果采访者不同意,他的牛肉是专家而不是你。)
多态性字面上的意思是"有能力接受多个形式或形状"。更广泛地说是,以对不同对象的引用能力来以不同方式表示同样的信息(或方法调用)。
Damian Conway, 在他的书Object-Oriented Perl中,意味深长地区别了二种多态性。一,继承多态性,是多数程序员提到多态性时所谈论到的哪个。
当一个类继承超类时,我们知道超类内出现的任何方法也在子类内出现。所以,继承链表示为一个可以对同名的方法集做出响 应的类的线性层次。当然,我们必须记住任何子类可以重新定义一个方法;这就是给予继承的力量。如果我在个对象上调用方法,典型地它即可是它从超类继承的方 法,也可以是它本身的更具体的方法。
在强类型语言如C++中,继承多态性建立在类型向继承链下面兼容之上(反过来不行)。例如,如果B继承A,那么指向A对象的指针同样可以指向一个B对象。但是反过来就不成立。在这样的语言中,类型兼容是基本的OOP特征,它们有多态性,而且是 缺乏静态类型下的多态性 (像 Ruby)。
第二种多态性是Conway指出的接口多态性。它不要求两个类之间有任何继承关系;它只要求对象的接口带有确定名字方法。这样对象被看做成是同一类东西,所以是多态的 (尽管大多数作者并不明确地这样引用)。

熟悉Java的读者认为它实现了两种多态性。Java类可以扩展另一个类,通过extends关键字来继承,或者它可以实现一个接口,通过关键字implements来获取一套已知的方法集(然后它们必须被覆写)。因为语法上要求,Java解释器可以在编译时决定哪个特定对象的方法被调用。
连接对被预计存在的用户定义的方法

Ruby以不同方式支持接口多态性,提供模块,它的方法可以被混合插入到现有类中(对用户定义的现存的方法的接口)。然而,这不是模块通常被使用的方式。模块由方法和常量组成,它可以被当做那个类或对象的真实部分使用;当模块通过include语句被混插时,这被认为是受限制的多重继承形式。(依照设计者Yukihiro Matsumoto,这可以被当做"实现共享的单继承"。) 这样可保留MI的好处,而不它的坏外。
值得注意地是,Ruby通过将任何类可以被"装扮"成另一个类来含蓄地支持接口多态性。在很多情况下,我们关心的唯一类型信息是,是否实现了一套方法,对象是否会对某些信息做出反应。有时候我们为一个Duck对象写代码时,我们所真正关心的它实现了一个quack方法。然而,如果有时候"quacks"像个Duck,出于我们自己的目的,它是一个Duck (完全不需要从那个类继承)。这套可用方法被认为是最重要的类型信息。
像C++这样的语言包含抽象类概念,这个类必须被继承并且不能实例化它们自己。这个概念在动态语言Ruby中不存在,尽管,如果程序员真需要,可以通过强制覆写方法这种行为来仿真也是可以。不管它是有用还是没有留给你做个练习吧!
C++的创始者,Bjarne Stroustrup,也确定具体类型的概念。这只是为了方便现存的类;它没被设计成继承形式,也不期望另外的类从它继承。换句话说,OOP的好处是对封装的基本限制。Ruby没有通过任何特殊语法来支持这个概念 (不像C++),但是它自然地适合于创建这样类。
一些语言认自己比其它语言是更面向对象的。(我们也使用术语真正对象导向的) 这儿提到的概念,语言内每个东西都是一个对象;每类基本类型都表示一个完整的类,变量和常量也被认是对象实例。这与这样的语言如Java, C++, 和Eiffel形成对比。在这些之中,大多数基本数据 (特别是常量)不是第一级别对象,尽管它们有时候可能被视为"被包装的"类。
大多数面向对象语言是相当静态的;方法和属性属于类,全局变量,并且继承体系编译时被定义。或许Ruby程序员的最大飞越是,在Ruby内所有这些都被动态处理。甚至定义和继承事实上在运行时发生,我们可以真正地说,每个声明或定义实际上是在程序运行期间被执行的。在这众多好处中,这排除了对条件编译的需要,并可以在很多情况下产生更有效率的代码。
这是对OOP的快速总结。在本书余下部分,我们要对这儿的术语的用途进行介绍。现在我们对Ruby语言本身进行简单回顾。




二、Basic Ruby Syntax and Semantics
Bring forth that ruby gem of Badakhshan,That heart's delight, that balm of Turkestan….

The Rubaiyat, Omar Khayyam (trans. E. H. Whinfield)

在前面,你已经看到Ruby是纯净的,动态的OOP语言。让我们在总结句法和语法之前,先简要看看其它一些属性。
Ruby是个脚本语言。这不应该被理解成它是不强大的。在KornShell和其它的传统中,它被认为是"胶水语言",或者它可以为创建大的自身包含应用程序提供一个环境。传统的KomShell等等中,它可用做创建大的自包含应用程序的环境。读者若对脚本语言感兴趣,应该参考John Ousterhout的1998年的作品"Scripting: Higher-Level Programming for the 21st Century"。
Ruby是解释语言。当然,这是Ruby编译器的最后实现所完成的理由, 但是我们主张,编译器产生的极大好处不只是快速的原型而是在于缩短开发周期。
Ruby是表达式导向的语言。当表达式能完成的时候为什么要使用语句?这个意思是,例如,代码会变得更紧凑并且重复被移除。
Ruby是真正的高级语言 (VHLL)。语言设计的背后原则是,计算机应该为程序员工作而不是相反。Ruby的"密度"意味着精练和复杂的操作相对与低级语言做比较,可更舒适地完成。
都会说,我们在紧盯着Ruby。本节和其余的章节将集中介绍Ruby语言本身。像前面说到的,这只是个快速总结,所以如果你还没有学习过它,那么你不应在这学习它。
我们不会先关心Ruby的语言的复杂特征。这儿只讨论下面二个部分。这儿从整体上浏览语言和它的一些术语。在看例子之前,我们将简短地查看Ruby程序的本质。
首先,Ruby本质上比其它语言如C更像行导向语言,但不像古董的语言如FORTRAN。记号会拥挤在一行上,只要它们按需要用空白分隔。如果用逗号分隔,一行可以有多个语句;只有当真正需要终止符号的时候。行可以被延续到下一行,这通过用一个反斜线或者让解析器知道本行没有完成,例如,通过在行尾加上一个逗号。
没有main程序;通常是从上向下执行。在更复杂的程序中,在顶部可能有很多定义,接下来的(概念上的)main程序在底部。但是,即使在那种情况,执行仍然是从顶向下,因为定义在Ruby内被执行。


1、关键字和标识符

Ruby内的典型的关键字(保留字)不能被用于其它目的。这些在下面列出:
BEGIN
END
alias
and
begin
break
case
class
def
defined
do
else
elsif
end
ensure
false
for
if
in
module
next
nil
not
or
redo
rescue
retry
return
self
super
then
true
undef
unless
until
when
while
yield

变量和通常的标识符开头是字母表内的字母或者是特殊修饰符。下面是基本规则:
1.
局部变量(和伪变量如self和nil)以小写字母开头。
2.
全局变量以美元符号($)
分享到:
评论

相关推荐

    ruby的概要介绍与分析

    下面是一系列精选的 Ruby 学习资源,旨在满足不同水平学习者的需求。 ### 官方文档与教程 - **Ruby 官方网站**:Ruby-lang.org 是 Ruby 语言的官方门户,提供了最新的 Ruby 版本下载、安装指南和详尽的官方文档。...

    计算机精品学习资料大放送

    经典LinuxCBT视频教程系列 Linux快速学习视频教程一帖通 天罗地网:精品Linux学习资料大收集(电子书+视频教程) Linux参考资源大系 Linux系统管理员必备参考资料下载汇总 Linux shell、内核及系统编程精品资料下载...

    Ruby On Rails开发从头来系列教程(chm)

    摘要:一直想尝试Ruby On Rails,但是因为对apache,mysql都不熟,对Rails的环境搭建更是没信心,所以一直没有开始,从知道了InstantRails后,终于在windows上搭建了Ruby On Rails开发环境,开始了Rails的学习。...

    Ruby语言教程&案例&相关项目资源

    这篇文章是一份全面而深入的Ruby语言学习资源指南,旨在为那些想要学习Ruby编程的开发者提供清晰的学习路径和实践机会。通过这篇文章,您将了解到Ruby语言教程、案例以及相关项目资源的丰富内容,从而能够系统地掌握...

    Matlab系列--学习各种语言的(c c++ java Python ruby MATLAB lingo math.zip

    Matlab系列--学习各种语言的(c c++ java Python ruby MATLAB lingo math

    ruby书籍1

    很全的ruby书籍系列之一,希望对大家学习ruby有帮助:)

    Ruby中使用SWIG编写ruby扩展模块实例

    在使用ruby/rails的过程中,确实发现有时性能不尽人意,如生成一个拥有600项的item的3层树形结构目录要花去20ms,为提高性能在学习用c/c++写ruby模块的过程中,认识了swig,rubyInline等一系列帮助编写c/c++来提升...

    gdi-ruby:为GDI设计的为期5周的Ruby编程课程

    是否想学习一种可用于构建Web应用程序和iPhone应用程序的语言,系统管理和安全性? 然后,您准备学习Ruby。 Ruby是一种开放源代码语言,可为Hulu,LivingSocial,Groupon和Github等应用程序和产品提供支持。 有一...

    Ruby编程之美:实用案例深度解析.zip

    本文通过一系列实用案例深入解析了Ruby编程的魅力和技巧。从文件操作、Web开发、网络编程到脚本自动化,Ruby都展现了其强大的功能和灵活性。通过学习和掌握这些案例中的技巧和方法,读者可以更好地应用Ruby进行实际...

    sketchup-rubyscript-tutorials:Google SketchUp 的 Ruby 脚本教程。 对于那些渴望创建一些常规计算几何的人。 并学习Ruby。 也许也学习编程

    Sketchup-rubyscript-教程这个存储库计划成为我的 rhino-pythonscript-tutorial 系列的 Sketchup Ruby 脚本实现。

    原始Ruby前功

    您如何创建一系列数字? 您如何将范围转换为数组,以便可以对其进行迭代? 要求: 不要使用任何其他Ruby库。 您必须构建一种可以验证数字是否为质数的方法。 require 'math' ,只需背负其素数的实现即可。先进的...

    code_quizzer, 使用 ruby JavaScript Rails 和Bash编程实践问题.zip

    code_quizzer, 使用 ruby JavaScript Rails 和Bash编程实践问题 CodeQuizzes关于站点在 ,Rails,JavaScript,Bash,git中包含一系列编程实践问题。 等等 !当我学习编程并决定创建CodeQuizzes作为我的第一个 Rails ...

    Ruby CGI 编程

    接下来,让我们花点时间来学习Ruby的CGI编辑。 网页浏览 为了更好的了解CGI是如何工作的,我们可以从在网页上点击一个链接或URL的流程: 1、使用你的浏览器访问URL并连接到HTTP web 服务器。 2、Web服务器接收到请求...

    prime-ruby-v-000

    您如何创建一系列数字? 您如何将范围转换为数组,以便可以对其进行迭代? 要求: 不要使用任何其他Ruby库。 您必须构建一种可以验证数字是否为质数的方法。 require 'math' ,只需背负其素数的实现即可。 先进的...

    Ric.Shreves.PDF文字版.pdf

    经典LinuxCBT视频教程系列 Linux快速学习视频教程一帖通 天罗地网:精品Linux学习资料大收集(电子书+视频教程) Linux参考资源大系 Linux系统管理员必备参考资料下载汇总 Linux shell、内核及系统编程精品资料下载...

    prime-ruby-online-web-prework

    您如何创建一系列数字?您如何将范围转换为数组,以便可以对其进行迭代?要求:不要使用任何其他Ruby库。您必须构建一种可以验证数字是否为质数的方法。 require 'math' ,只需背负其素数的实现即可。先进的考虑一下...

    open cv 视频学习

    open CV学习视频 OpenCV是一个基于BSD许可(开源)发行的跨...它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。

    prime-ruby-onl01-seng-pt-052620

    您如何创建一系列数字? 您如何将范围转换为数组,以便可以对其进行迭代? 要求: 不要使用任何其他Ruby库。 您必须构建一种可以验证数字是否为质数的方法。 require 'math' ,只需背负其素数的实现即可。 先进的...

    prime-ruby-online-web-sp-000

    您如何创建一系列数字?您如何将范围转换为数组,以便可以对其进行迭代?要求:不要使用任何其他Ruby库。您必须构建一种可以验证数字是否为质数的方法。 require 'math' ,只需背负其素数的实现即可。先进的考虑一下...

    计算机视觉+机器学习+OpenCV

    [1] 它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。 该开发包合集,是笔者花了2天时间,从OpenCV官网...

Global site tag (gtag.js) - Google Analytics