二十分钟Ruby入门
cleverpig 发表于 2007-02-26 10:42:28作者:cleverpig 来源:Matrix
评论数:39 点击数:267,374 投票总得分:30 投票总人次:6
关键字:Ruby,20分钟,快速入门,
摘要:
这是一个短小的Ruby入门,完全读完只需20分钟。让我们从编写世界上最简单的"Hello,World"程序开始逐步深入了解Ruby的类、block、迭代器等特征,也许这对你来讲还远远不过,但对于20分钟的入门来讲已经非常难得了。作者:cleverpig

介绍
这是一个短小的Ruby入门,完全读完只需20分钟。这里假设读者已经安装了Ruby,如果你没有安装的话,请在阅读文前访问Ruby官方网站进行下载并安装。
交互式的Ruby
打开IRB(交互式Ruby外壳):
如果你使用Mac OS X,那么请打开终端窗口输入irb;
如果你使用Linux,那么请打开shell输入irb;
如果你使用windows,那么请在开始菜单中找到Ruby->fxri,并执行它。
Ok,在打开IRB之后,在其中输入"Hello World"。

Ruby听从你的安排!
发生了什么?我们刚才编写了世界上最短小的“Hello World”程序吗?这么说不太确切。第二行输出是IRB告诉我们:上一个表达式的评估结果。如果我们希望打印出“Hello World”,那么就还需要一点努力:

puts在Ruby中是一个简单的打印输出命令。后面的“=> nil”表示什么?——那是表达式的结果。Puts总是返回nil,这是Ruby中表示“绝对无值”(absolutely-positively-nothing value)的方式,看上去有些类似Java中的null。
你的免费计算器在这里!
无需做什么,我们就能把IRB作为一个简单的计算器使用:

这样就能计算3+2。够简单的!那么3乘以2如何?你可以在下面继续输入3*2,也可以回到上面(3+2处)重新修改你刚刚输入的计算公式。使用键盘上的向上键,使光标到达3+2那一行,再用左键移动光标到加号上,然后使用空格键进行修改。
下面,让我们尝试计算3的平方:
在Ruby语言中,**表示幂运算。那么如何计算平方根呢?

Ok,等一下,表达式中的sqrt(9)表示什么?你一定能猜到这是计算9的平方根。而Math表示什么?不要着急,下面就让我们进一步了解像Math这样的模块。
模块——按照主题分组的代码
Math是Ruby内建的数学模块。在Ruby中,模块提供了两种角色:一种角色是将类似的方法聚集在同一个“家族”名下。因此,Math也包括sin、tan这样的方法。第二种角色是一个圆点(dot),它标记了消息的接收者。什么是消息?在上面的例子中,sqrt(9)便是消息,它意味着调用sqrt方法取出9的平方根。
Sqrt方法调用的结果是3.0。你可能注意到它并不是3。这是因为多数情况下,数字的平方根并不是整数,所以这里返回了一个浮点数。
那么我们如何记住这些计算结果呢?——将结果赋值给变量。

如何定义方法?
如何才能方便省事地随意输出字符串,而无需过多地劳烦我们的手指呢?——我们需要定义一个方法!

上面的代码中第一行“def h”标志着方法定义的开始。它告诉Ruby我们正在定义一个名为h的方法。下面一行是方法体:puts "Hello World"。最后,也就是第三行“end”通知Ruby我们完成了方法定义。Ruby的回应“=> nil”告诉我们它已经知道我们定义了此方法。
简短、重复地调用方法
现在,让我们尝试多次执行这个方法:
哈,这太容易了。在Ruby中调用某个方法只需将方法名提交给Ruby。当然,这是在方法没有参数的情况下。如果你愿意也可以添加一个空白的括号,但是这没有必要。
如果我们想对某个人说hello而不是整个“世界”(world),那该怎么做?——重定义h方法使它接收name参数。

嗯,现在看来工作正常。
字符串中的奥秘
“#{name}”是什么意思?这是Ruby在某个字符串中插入其它字符的方式。在大括号之间放入的字符串(这里是指name)将被外部的字符串代替。你也可以使用字符串类内建的capitalize方法来确保某人名字的首字母大写:

上面的代码有两个地方需要说明:
第一,我们通过无括号的方式调用方法,因为括号是可选的;
第二,这里的默认参数值为“World”。也就是说在调用方法时如果没有提供name参数,则使用默认值“World”。
进化为Greeter!
我们是否需要一个真正的问候者(greeter),他能记住你的名字、问候你、总是尊重地向你示好?那么这就最好建立一个“Greeter”类:

在上面的类代码中定义了一个称为Greeter的类和一些类方法,其中出现了一些新的“关键词”:请注意“@name”,它是类的实例变量,并对类中的所有方法(say_hi和say_bye方法)都有效。
如何让Greeter类发挥作用?现在让我们来建立一个Greeter对象并使用它!

Greeter类的实例对象g被建立后,它便接受了name参数(值为Pat)。那么我们能直接访问name吗?

看看上面的编译错误来看,这样直接访问name是行不通的。
窥视对象的内部
对象中的实例变量总是隐藏于其中,但也并非毫无踪迹可寻,通过审查(inspect)对象便会见到它们。当然还有其它的访问方法,但是Ruby采用了良好的面向对象的方式来保持数据的隐藏性。

喔!这么多方法,可是我们只定义了两个方法呀?其它的方法又出自何处?不要担心,instance_methods方法列出了Greeter对象的所有方法,其中包括父类中定义的方法。如果我们只想对Greeter类的方法进行列表的话,那么把false作为参数调用instance_methods方法即可。false意味着我们不需要父类定义的方法。

哈哈,这才是我们想要的。下面让我们看看Greeter对象能回应哪些方法:

它知道say_hi、to_s(此方法将对象转换为字符串,是任何对象都必备的默认方法,很想Java中的toString方法),但它不知道name。
随时修改类定义
如何才能查看或者修改name呢?Ruby提供了访问对象变量的简单方法:

在Ruby语言中,你能够多次打开某个类并修改它。而修改所带来的变化将应用在此后建立的任何新对象中、甚至现存的此类对象中。下面让我们建立一个新对象并访问它的@name属性。

我们通过使用attr_accessor定义了两个方法:
“.name”用来获取name属性值;
“.name=”用来设置namee属性值。
这很类似在Java类中访问被Public修饰的成员变量。
向每个人问候,MegaGreeter不会漏掉一个人
Greeter并不完美,因为它只能一次服务一个人。所以我们在这里设计一个能够一次向全世界、世界上每个人或者在名单中的人发送问候的MegaGreeter类。在这里,我们将放弃从前的IRB交互模式,转而改为编写Ruby程序文件。
退出IRB的方法:输入“quit”、“exit”或者按下Control+D的组合键。

保存上面的代码到名为“ri20min.rb”的文件中,并使用“ruby ri20min.rb”的命令执行它。程序输出如下:

下面我们将深入了解一下上面的代码。
请注意上面代码中的起始行,它以#开头。在Ruby语言中,任何以#开头的行都被视为注释,并被解释程序忽略。
我们的say_hi方法已经发生了变化:

它查找@names参数并按照其参数值作出决定:
如果参数值为nil,它将打印三个圆点。
那么@names.respond_to?("each")表示什么?
循环——也叫迭代
如果@names对象具有each方法,那么它是可以被迭代的,进而可以对其进行迭代,从而问候列表中每个人。如果@names不具备each方法,则将它自动转换为字符串,并执行默认的问候。

each是一种方法,它接受一个代码块(block of code),然后针对列表中的每个成员执行这个代码块,而在do和end之间的部分便是这个非常类似匿名函数的代码块。在管道符之间的变量是代码块的参数name,它作为代码块参数被绑定为列表成员,而代码块puts "Hello #{name}!"将使用这个参数进行输出。
大多数其它的编程语言使用循环遍历列表,下面是C语言的循环示例:

上面的代码显然可以工作,但它不够“优雅”!你不得不用i这个多余的循环变量,还需要指出列表的长度,然后再解释如何遍历列表。
Ruby的迭代方式则更加优雅,所有的内部管理细节都隐藏在each方法中,你所需做的就是告诉它如何处理其中的每个成员。
块(block),Ruby边缘的高亮点!
块(block)的真正优势在于:能够处理比列表更加复杂的对象。除了在方法中可以处理简单的内部管理细节外,你还能处理setup、teardown和所有错误,而不让用户有所察觉。

say_bye方法没有使用each,而是检查@names是否具有join方法,如果具有join方法,则调用join方法。否则它将直接打印@names变量。
此方法并不关心变量的实际类型,这依赖于它所支持的那些被称为“Duck Typing”的方法:duck typing是动态类型的一种形式:变量的值自身隐含地决定了了变量的行为。这暗示了某个对象与其它实现了相同接口的对象之间是可交换的,不管对象之间是否具有继承关系。鸭子测试(duck test)是对duck typing的一种形象比喻——“如果它走路像鸭子,那么也一定像鸭子一样呷呷地叫,那么它必定是一只鸭子”。duck typing是某些编程语言的特性:如Smalltalk, Python, Ruby, ColdFusion。
Duck Typing的益处是无需对变量的类型进行严格地限制,如果某人使用一种新类型的列表类,只要它实现了与其它列表相同语义的join方法,便可以拿来使用。
启动脚本
文件上半部分是MegaGreeter类的代码,而后面剩下的部分则是对这些类方法的调用。而这是我们最后值得注意的一点:

__FILE__是一个“具有魔力”的变量,它代表了当前文件名。$0是用于启动程序的文件名。那么代码“if __FILE__ == $0”便意味着检查此文件是否为将被使用的主程序文件。这样做可以使程序文件作为代码库使用,而不是可执行代码;但当此文件被用作执行文件时,也可被执行。
如何进一步学习Ruby
到此便是本入门的尾声了。当然还有许多值得浏览的:Ruby提供的各种不同的控制结构;块和yield的使用;模块作为mixins使用等。希望这次Ruby初体验能使你对Ruby更感兴趣。
注:mixin在面向对象编程语言中是一种提供某些功能给子类继承的类,但mixin并不能实例化。从某个mixin继承并不是什么特殊的形式,而它更适于收集功能。某个子类甚至可以通过继承一个或者多个mixin选择继承它的全部或者多数功能。一个mixin能延期定义和绑定方法直到运行时,而属性和实例参数也将在编译时才被定义。这不同于多数常见的方式:定义所有的属性、方法,并在编译时进行初始化。
如果这样的话,请埋头翻阅我们的文档,那里有免费、丰富的在线手册和入门资源。或者如果你喜欢在啃书本的话,可以到图书列表中选择一些你所需要的。
相关资源
下载Ruby
Ruby官方文档
Ruby出版图书列表
用于Eclipse的Ruby开发插件
Ruby in Twenty Minutes
Ruby函数式风格编程
用block简化编程一例
迭代器+代码块,让代码更简短
感谢阅读此文
请支持cleverpig发起的

本页页面地址:
用户评论列表
谢谢。简介明了,希望cleverpig可以把自己的经验继续给大家提供。
谢谢,挺好的。只是不知道,这种东西有如何使用,学习一下。
谢谢,挺好的。只是不知道,这种东西有如何使用,学习一下。
支持,有时间也应该学习了解这个技术了
有时间要好好看看这个
这真是一篇不错的Ruby入门文章,看过以后我也可以在自己的机器上操练两下子了。呵呵!
感谢cleverpig君。
Ruby与Python有什么区别?哪个更好用些?
To pytruth1002同学:
和Python不同,Ruby具有以下的特点:
1.字符串是可变的。
2.可以使用常量。
3.存在一些强制大小写转换规则(比如:类名以大写字母开头,变量以小写字母开头)
4.Ruby只有一种列表容器(数组),而且它是可变的。
5.双引号修饰的字符串可用换码序列(escape sequences)和特定的正则表达式替换语法。
6.Ruby没有新风格类和旧风格类,而只有一种类。
7.不能直接访问对象属性,只能通过方法调用做的。
8.调用方法时,括号可以省略。
9.Ruby使用public、private、protected来增强类访问模式,而Python则采用_voluntary_、underscore、__convention__。
10.采用Mixin替代了多重继承。
11.在任何时候都能重新打开类,并做修改,使之在随后生效。
12.Ruby使用true和false代替了Python的True和False,nil代替了Python的None。
13.在进行代码测试时,只有false和nil代表了false,而其它都表示true(包括0,0.0,””,和[])。
14.使用elsif代替了Python的elif。
15.使用require代替了Python的import。
16.在代码上方使用常见风格的单行或者多行注释,代替了Python在代码下方的docstrings。
17.Ruby提供了一下快捷方式,使开发更加高效。
大家可以看一下online语法比较,可以形象了解一下:http://www.dmh2000.com/cjpr/cmpframe.html
很好的入门文章,最近总有同事谈论Ruby,我自己也可以试试了。
非常感谢!
不错不错,非常好!真是简单易懂。
好,适合我这种初学者
非常感谢楼主的回答。
Ruby与Python同为动态脚本语言,除了语言语法方面的区别之外,我更想知道他们在应用方面有什么区别。可否推荐些Ruby应用的实际Demo!
to pytruth1002:
可以看看http://poignantguide.net/ruby/
或者http://tryruby.hobix.com/
ruby语言究竟会如何?
不错不错,非常好!非常感谢!
没找到中文版的ruby的简易语法说明
python就有,当时看了几天就基本掌握了基本语法
可惜python的web开发远没有ror火
不得不转而学起了ruby
这个算术题作校验,有点意思
是为了防止发帖机器人?
fxri太吃内存了!!!
i just passby!
i just passby!
i just passby!
i just passby!
i just passby!
I just pass by too : ) Cool!
ModPython开发Web应用也很不错。既生Python,何生Ruby!
9.Ruby使用public、private、protected来增强类访问模式,而Python则采用_voluntary_、underscore、__convention__。
10.采用Mixin替代了多重继承。
11.在任何时候都能重新打开类,并做修改,使之在随后生效。
这3条比较有趣,尤其是11,动态修改类是个很另类的想法,但是我总感觉既然用oo,那么类一定要实现设计好,否则虽然灵活性增加了,但是效率和代码的完整性上肯定要大打折扣。
其他看起来跟python好像差不多哦,感觉是个python的变形版。这个东西有一个可以给日汉字标注假名的功能,比较好玩。
关于文章 中代码的 image 图片都看不到 。怎么办 ?
如果有办法最好 ,这篇文章对我很有帮助
欢迎大家光临 Ruby中文社区进行讨论,共同学习
Ruby中文社区
楼主要是给一本学习ruby的书就好了!!支持了!
哥们,哈哈,偶也是为了工作哈。。。
===============================
RORChina中国社区门户, 专注于Ruby和Rails技术, 欢迎在LUPA关注Ruby/Rails技术的朋友加入红魔社区。
门户:http://www.rorchina.net/
论坛:http://www.rorchina.net/bbs/
热情体验中ing...
USFINE.COM sell World of Warcraft gold and
wow powerleveling sevise.
USFINE.COM sell World of Warcraft gold and
wow powerleveling sevise.
USFINE.COM sell World of Warcraft gold and
wow powerleveling sevise.
欢迎大家光临 Ruby Blog进行讨论,共同学习.http://www.everyone-4649.com/
欢迎大家光临 Ruby Blog进行讨论,共同学习.http://www.everyone-4649.com/
欢迎大家光临 Ruby Blog进行讨论,共同学习.http://www.everyone-4649.com/
发表我的评论 (评论可增加个人积分...)
| 用户*: | E-mail: | ||
| 评论内容*: 支持BBCode |
|||
| 算术题*: | + = | ||

ICP:?B2-20040367