- 浏览: 454889 次
文章分类
最新评论
-
yintingbird:
没有啊,网址在哪里,只有一个标题和对标题的描述。。。
推荐一个很棒的API搜索引擎 -
javer:
灰常感谢!
SWT中获取字符串占用像素数 -
werwolf:
Page View 现在怎么样了?
Page View 将死? -
liulehua:
恩,就是这个问题。
解决java.lang.UnsupportedClassVersionError问题!! -
norwaywoods:
扯淡。。。
平台相关性与平台无关性
Ruby FAQ
1. 一般的问题
2. 变量、常数、参数
3. 调用带块方法(迭代器)
4. 句法
5. 方法
6. 类、模块
7. 内部库
8. 扩展库
9. 尚未列出的功能
10. 日语字符的处理
11. Ruby的处理系统
一般的问题
* 1.1 Ruby是什么?
* 1.2 为什么取名叫Ruby呢?
* 1.3 请介绍一下Ruby的诞生过程
* 1.4 哪里有Ruby的安装文件?
* 1.5 请问Ruby的主页在哪里?
* 1.6 请问有Ruby邮件列表吗?
* 1.7 怎么才能看到邮件列表中的老邮件?
* 1.8 rubyist和ruby hacker的区别是什么?
* 1.9 它的正确写法是"Ruby"还是"ruby"?
* 1.10 请介绍一些Ruby的参考书
* 1.11 我看了手册可还是不明白,该怎么办?
* 1.12 ruby的性格比较像羊?
* 1.13 遇到bug时怎么上报?
变量、常数、参数
* 2.1 将对象赋值给变量或常数时,会先拷贝该对象吗?
* 2.2 局部变量的作用域是如何划定的?
* 2.3 何时才能使用局部变量?
* 2.4 常数的作用域是如何划定的?
* 2.5 实参是怎么传递给形参的呢?
* 2.6 将实参赋值给形参之后,对实参本身有什么影响吗?
* 2.7 若向形参所指对象发送消息的话,可能出现什么结果?
* 2.8 参数前面的*是什么意思?
* 2.9 参数前面的&代表什么?
* 2.10 可以给形参指定默认值吗?
* 2.11 如何向块传递参数呢?
* 2.12 为什么变量和常数的值会自己发生变化?
* 2.13 常数不能被修改吗?
调用带块方法
* 3.1 什么是"带块的方法调用"?
* 3.2 怎么将块传递给带块方法?
* 3.3 如何在主调方法中使用块?
* 3.4 为什么Proc.new没有生成过程对象呢?
句法
* 4.1 像:exit这种带:的标识符表示什么?
* 4.2 如何取得与符号同名的变量的值?
* 4.3 loop是控制结构吗?
* 4.4 a +b报错,这是怎么回事儿?
* 4.5 s = "x"; puts s *10 报错,这是怎么回事儿?
* 4.6 为什么p {}没有任何显示呢?
* 4.7 明明有pos=()这样的setter方法,可为什么pos=1时却没有任何反应呢?
* 4.8 '\1'和'\\1'有什么不同?
* 4.9 在p true or true and false中会显示true,但在a=true if true or true and false中却不会把true赋值给a。
* 4.10 为什么p(nil || "")什么事儿都没有,可p(nil or "")却会报错呢?
方法
* 5.1 向对象发出消息之后,将按照什么顺序来搜索要执行的方法?
* 5.2 +和-是操作符吗?
* 5.3 Ruby中有函数吗?
* 5.4可以在外部使用对象的实例变量吗?
* 5.5 private和protected有什么不同?
* 5.6 能不能将实例变量变成public类型的变量?
* 5.7 怎样指定方法的可见性?
* 5.8 方法名可以用大写字母开头吗?
* 5.9 为什么使用super时会出现ArgumentError?
* 5.10 如何调用上2层的同名方法?
* 5.11 重定义内部函数时,如何调用原来的函数?
* 5.12 何谓破环性的方法?
* 5.13 那些情况下会产生副作用?
* 5.14 能让方法返回多个值吗?
类、模块
* 6.1 重定义类时,是否会覆盖原来的定义?
* 6.2 有类变量吗?
* 6.3 什么是类的实例变量?
* 6.4 什么是特殊方法?
* 6.5 什么是类方法?
* 6.6 什么是特殊类?
* 6.7 什么是模块函数?
* 6.8 类和模块有什么区别?
* 6.9 模块可以生成子类吗?
* 6.10 在类定义中定义类方法 和 在顶层中定义类方法 之间有什么不同?
* 6.11 load和require有什么不同?
* 6.12 include和extend有什么不同?
* 6.13 self是什么?
* 6.14 MatchData中的begin、end分别返回什么?
* 6.15 如何使用类名来获得类?
内部库
* 7.1 instance_methods(true)返回什么?
* 7.2 为什么rand总是生成相同的随机数?
* 7.3 怎样从0到51中选出5个不重复的随机数呢?
* 7.4 Fixnum、Symbol、true、nil和false这些立即值与引用有什么不同?
* 7.5 nil和false有什么不同?
* 7.6 为什么读入文件并修改之后, 原文件依然没有变化?
* 7.7 怎样覆盖同名文件?
* 7.8 写文件后拷贝该文件,但所得副本并不完整,请问原因何在?
* 7.9 在管道中将字符串传给less后, 为什么看不到结果?
* 7.10 无法引用的File对象将会何去何从?
* 7.11 怎样手动关闭文件?
* 7.12 如何按照更新时间的新旧顺序来排列文件?
* 7.13 如何获取文件中单词的出现频度?
* 7.14 为什么条件表达式中的空字符串表示true呢?
* 7.15 如何按照字典顺序来排列英文字符串数组?
* 7.16 "abcd"[0]会返回什么?
* 7.17 怎么把tab变成space?
* 7.18 如何对反斜线进行转义操作?
* 7.19 sub和sub!的区别在哪里?
* 7.20 \Z匹配什么?
* 7.21 范围对象中的..和...有什么不同?
* 7.22 有函数指针吗?
* 7.23 线程和进程fork有何异同?
* 7.24 如何使用Marshal?
* 7.25 Ruby有异常处理语句吗?
* 7.26 如何使用trap?
* 7.27 如何统计文件的行数?
* 7.28 怎样把数组转化为哈希表?
* 7.29 将字符串变为Array时可以使用%w(...),那么将字符串变为Hash时能不能如法炮制呢?
* 7.30 为何无法捕捉NameError异常呢?
* 7.31 为什么有succ却没有prev呢
扩展库
* 8.1 如何使用交互式Ruby?
* 8.2 有调试器吗?
* 8.3 怎样在Ruby中使用以C写成的库?
* 8.4 有Tcl/Tk的接口吗?
* 8.5 为什么我的Tk不管用?
* 8.6 有gtk+、xforms的接口吗?
* 8.7 进行日期计算时需要注意哪些问题?
尚未列出的功能
日语字符的处理
* 10.1 若包含汉字的脚本输出乱码或无法正常运行时,该如何处理?
* 10.2 选项-K和$KCODE有什么不同?
* 10.3 可以使用日语标识符吗?
* 10.4 如何从包含日语字符的字符串中依次抽出1个字符?
* 10.5 tr("あ","a")运作不正常,应如何处置?
* 10.6 如何对平假名进行排序?
* 10.7 如何用空白来替代SJIS中从84BF到889F之间的系统相关代码?
* 10.8 如何进行全角-半角字符的变换?
* 10.9 关于半角假名的问题
* 10.10 怎样从包含日语字符的字符串中抽出n字节的内容?
* 10.11 怎么让日语文本在第n个字处换行?
Ruby的处理系统
* 11.1 能不能编译Ruby脚本呢?
* 11.2 有没有Java VM版的Ruby?
* 11.3 除了original Ruby之外,就没有其他版本吗?
* 11.4 有没有Ruby用的indent?
* 11.5 有没有使用本地线程的Ruby?
* 11.6 GC实在是太慢了,怎么办才好?
* 11.7 有没有Mac版的Ruby?
1. 一般的问题
* 1.1 Ruby是什么?
* 1.2 为什么取名叫Ruby呢?
* 1.3 请介绍一下Ruby的诞生过程
* 1.4 哪里有Ruby的安装文件?
* 1.5 请问Ruby的主页在哪里?
* 1.6 请问有Ruby邮件列表吗?
* 1.7 怎么才能看到邮件列表中的老邮件?
* 1.8 rubyist和ruby hacker的区别是什么?
* 1.9 它的正确写法是"Ruby"还是"ruby"?
* 1.10 请介绍一些Ruby的参考书
* 1.11 我看了手册可还是不明白,该怎么办?
* 1.12 ruby的性格比较像羊?
* 1.13 遇到bug时怎么上报?
1.1 Ruby是什么?
一言以蔽之,Ruby是一种
语法简单且功能强大的面向对象的脚本语言。
与perl一样,Ruby的文本处理功能十分强大。当然了它的功能远不止于此,您还可以使用它来开发实用的服务器软件。
Ruby博采众长,吸收了众多语言的优点,却又别具一格。
Ruby的优点主要体现在以下几个方面。
* 它的语法简单
* 它具有普通的面向对象功能(类、方法调用等)
* 它还具有特殊的面向对象功能(Mix-in、特殊方法等)
* 可重载操作符
* 具有异常处理功能
* 调用带块方法(迭代器)和闭包
* 垃圾回收器
* 动态载入(取决于系统架构)
* 可移植性。它可以运行在大部分的UNIX、DOS和Mac上
1.2 为什么取名叫Ruby呢?
松本先生曾经在[ruby-talk:00394][英译稿](June 11, 1999)中讲过取名的经过。
据说当初松本先生一直琢磨着要给这个新语言取个像Perl这样的宝石名字,正好有个同事的诞生石是Ruby,因此就取名叫Ruby了。
后来发现Ruby和Perl真的很投缘,例如pearl诞生石代表6月,而ruby诞生石则代表7月。还有pearl的字体大小是5pt,而ruby则是5.5pt等等。因此松本先生觉得Ruby这个名字很合适,并努力使其成为比Perl更新更好的脚本语言。
松本先生正期待着Ruby取代Perl的那一天早点到来(^^)。
1.3 请介绍一下Ruby的诞生过程
松本先生曾经在[ruby-talk:00382][英译稿](June 4, 1999)中介绍过Ruby的诞生过程。[ruby-list:15997]修改了Ruby的诞生时间。
*
Ruby诞生于1993年2月24日。那天我和同事们聊了聊面向对象语言的可能性问题。我了解Perl(Perl4而非Perl5),但我不喜欢它身上的那股玩具味儿(现在也是如此)。面向对象的脚本语言的前途一片光明。
我觉得Python不能算作真正的面向对象语言,因为它的面向对象特性好像是后加进去的一样。15年来我一直为编程语言而痴狂,我热衷于面向对象编程,但却没有找到一款真正意义上的面向对象的脚本语言。
于是我下定决心自己来开发一个。经过几个月的努力,解释器终于开发成功。然后我又添加了一些自己梦寐以求的东西,如迭代器、异常处理、垃圾回收等。
后来我又采用类库方式添加了Perl的特性。1995年12月,我在日本国内的新闻组上发布了Ruby 0.95版本。
接下来我创建了邮件列表和网站。此后,大家在邮件列表中聊得酣畅淋漓。时至今日,第一个邮件列表中已经积累了14789封邮件。
Ruby 1.0发布于1996年12月,1.1发布于1997年8月。1998年12月,我又发布了安定版1.2和开发版1.3。
1.4 哪里有Ruby的安装文件?
您可以在这里<URL:ftp://ftp.ruby-lang.org/pub/ruby/>找到最新版的Ruby。
镜像站点列表如下
* <URL:ftp://ftp.TokyoNet.AD.JP/pub/misc/ruby/>
* <URL:ftp://ftp.iij.ad.jp/pub/lang/ruby/>
* <URL:ftp://blade.nagaokaut.ac.jp/pub/lang/ruby/>
* <URL:ftp://ftp.krnet.ne.jp/pub/ruby/>
* <URL:ftp://mirror.nucba.ac.jp/mirror/ruby/>
* <URL:http://mirror.nucba.ac.jp/mirror/ruby/>
您可以在Ruby Binaries中找到cygwin版、mingw版和djgpp版的二进制文件包。
另外,Windows(cygwin)中还为初学者准备了Ruby Entry Package。安装方法请参考面向初学者的Ruby安装说明。
1.5 请问Ruby的主页在哪里?
Ruby的官方网站是<URL:http://www.ruby-lang.org/>。
1.6 请问有Ruby邮件列表吗?
现在有6个正式的Ruby邮件列表。
* ruby-list
* ruby-dev
* ruby-ext
* ruby-math
* ruby-talk
* ruby-core
详情请参考Ruby邮件列表。
1.7 怎么才能看到邮件列表中的老邮件?
<URL:http://blade.nagaokaut.ac.jp/ruby/ruby-list/index.shtml>和<URL:http://ruby.freak.ne.jp/>里面有搜索邮件用的表单。
另外,ML Topics中列出了老邮件中的重要话题。
1.8 rubyist和ruby hacker的区别是什么?
松本先生对rubyist和Ruby hacker的定义如下。
rubyist是指那些对Ruby的关心程度超过常人的人。例如
* 向周围的人宣传Ruby的人
* 编写Ruby的FAQ的人
* 在计算机通信组中增加Ruby小组的组长
* 撰写Ruby书籍的作者
* 写信鼓励Ruby作者的热心人
* Ruby作者本人 ^^;;;
而Ruby hacker是指那些在技术层面上对Ruby有所专攻的人。例如
* Ruby扩展库的作者
* 修改Ruby中的bug并发布补丁的人
* djgpp版Ruby或win32版Ruby的作者
* 用Ruby编写了实用(必须得具备一定规模的)程序的人
* 用Ruby编写出天书般难懂的脚本的人
* Ruby作者本人 ^^;;;
等就是Ruby hacker。
这些称号只不过是自我解嘲式的自称,我不会为任何人进行正式的认证。松本先生特别将上述人士列为{rubyist、Ruby hacker},可见其尊敬之情。
1.9 它的正确写法是"Ruby"还是"ruby"?
Ruby的正式写法是"Ruby",其命令名是"ruby"。另外只要不让人觉得别扭的话,也可以使用ruby来替代Ruby。
但不能把"RUBY"、"ルビー"或"るびー"用作这门语言的名称。
此前曾经有一段时间把"ruby"用作正式名称。
1.10 请介绍一些Ruby的参考书
主要有《オブジェクト指向スクリプト言語Ruby》(译注:日语书名未翻译)[松本行弘/石塚圭树 合著 ASCII出版(ISBN4-7561-3254-5)],其他书目请参考Ruby相关书籍。
至于正则表达式,请参考Jeffrey E. F.Friedl著的《詳説正規表現》(译注:日语书名未翻译)[reilly Japan出版(ISBN4-900900-45-1)]。这本书介绍了各种正则表达式的实现问题,有助于加深您对于Ruby正则表达式的理解。
1.11 我看了手册可还是不明白,该怎么办?
Ruby的基本句法从Ruby1.0以后就没有太大的变化,但却在不断完善和扩充,因此有时文档的更新速度跟不上最新的发展。另外,有人坚持说源代码就是文档,如此种种。
若您有何疑问,请不必顾虑太多,直接到ruby-list中提问即可。Ruby教主松本先生以及各位尊师还有我都会为您排忧解难。
提问时,请写明ruby -v的结果并附带上您的代码(若代码太长的话,只需摘录重要部分即可)。
若您使用的是irb的话,则稍有不同。因为irb自身也存在一些问题,所以您最好先用irb --single-irb重试一下,或者用ruby重新运行一次为好。
虽然搜索ML可以解决您的大部分问题,但因为邮件数量庞大,想找到答案实属不易。为遵从网络礼节(请参考RFC1855的3.1.1、3.1.2),您可以只搜索最近的内容,但是说起来容易,做起来难。况且说不定最近又出现了什么新观点呢。所以您还是壮起胆子来提问吧。
1.12 ruby的性格比较像羊?
羊、蜂鸟、兔子...
1.13 遇到bug时怎么上报?
遇到bug时应该上报到Ruby Bug Tracking System,通常很快就会得到回复。您也可以用邮件将bug的情况上报到ruby-bugs-ja。
上报时,最好能提供ruby的版本和平台信息、错误消息以及能再现bug的脚本和数据。
遇到bug时,通常会显示[BUG]消息,而Ruby也将被强行关闭。此时大部分系统都会生成一个core文件。若您的调试器可用的话,可能还会有backtrace。若您能提供这些信息就更好了。
2. 变量、常数、参数
* 2.1 将对象赋值给变量或常数时,会先拷贝该对象吗?
* 2.2 局部变量的作用域是如何划定的?
* 2.3 何时才能使用局部变量?
* 2.4 常数的作用域是如何划定的?
* 2.5 实参是怎么传递给形参的呢?
* 2.6 将实参赋值给形参之后,对实参本身有什么影响吗?
* 2.7 若向形参所指对象发送消息的话,可能出现什么结果?
* 2.8 参数前面的*是什么意思?
* 2.9 参数前面的&代表什么?
* 2.10 可以给形参指定默认值吗?
* 2.11 如何向块传递参数呢?
* 2.12 为什么变量和常数的值会自己发生变化?
* 2.13 常数不能被修改吗?
2.1 将对象赋值给变量或常数时,会先拷贝该对象吗?
变量和常数都指向一个对象。即使不赋值, 它也是指向nil对象的。赋值操作只不过是让它指向另一个新对象而已。
所以, 赋值时并不会拷贝并生成一个新对象. 而是让赋值表达式左边的变量或常数指向表达式右边的对象。
尽管如此, 可能还是有人不理解. 这也是情有可原的, 因为上面的解释并不能涵盖所有的情况. 实际上, Fixnum、NilClass、 TrueClass、FalseClass以及Symbol类的实例会被变量或常数直接保存, 所以赋值时会被拷贝。其他类的实例都在内存上的其他地方, 变量和常数会指向它们。请参考立即值和使用。
2.2 局部变量的作用域是如何划定的?
顶层、类(模块)定义或方法定义都是彼此独立的作用域。另外, 在块导入新的作用域时, 它还可以使用外侧的局部变量。
块之所以与众不同, 是因为这样能够保证Thread或过程对象中的局部变量的"局部性"。while、until、for是控制结构, 它们不会导入新的作用域。另外, loop是方法, 它的后面跟着块。
2.3 何时才能使用局部变量?
在Ruby解释器运行Ruby脚本时, 它会一次读取整个脚本,然后进行语法分析。若没有语法问题的话, 才会开始执行句法分析中得到的代码。
在进行语法分析时, 只有在遇到局部变量的赋值语句之后, 才能使用它。例如
for i in 1..2
if i == 2
print a
else
a = 1
end
end
把上述代码写入名为test.rb的脚本. 执行该脚本后发生如下错误
test.rb:3: undefined local variable or method `a' for
#<Object:0x40101f4c> (NameError)
from test.rb:1:in `each'
from test.rb:1
当i值为1时,并不会发生错误;当i变成2之后就不行了。这是因为, 在进行语法分析时并不会按照运行时的逻辑顺序来进行, 而只是机械地逐行分析. 在遇到print a语句时, a并未被赋值, 因而无法使用该局部变量. 之后,在运行时因为找不到名为a的方法, 所以发生错误。
相反地, 若使用如下脚本则不会出现错误。
a = 1 if false; print a
#=> nil
若您不想因为局部变量的这个特性而费神的话, 我们推荐您在使用局部变量之前, 添加a = nil赋值语句。这样作还有一个好处, 就是可以加快局部变量的使用速度。
2.4 常数的作用域是如何划定的?
类/模块中定义的常数可以用在该类/模块中。
若类/模块定义发生嵌套时, 可在内侧类/模块中使用外侧的常数。
还可以使用超类以及包含模块中的常数。
因为顶层中定义的常数已经被添加到Object类中, 所以您可以在所有的类/模块中使用顶层中的常数。
若遇到无法直接使用的常数时, 可以使用 类/模块名+::操作符+常数名 的方式来使用它。
2.5 实参是怎么传递给形参的呢?
方法调用时, 会把实参赋值给形参。请您参考向变量进行赋值来了解Ruby中赋值的含义。若实参中的对象包含可以改变自身状态的方法时,就必须注意其副作用(当然了,也有可能不是副作用)了。请参考破坏性的方法。
2.6 将实参赋值给形参之后,对实参本身有什么影响吗?
形参是局部变量, 对其进行赋值之后, 它就会指向其他对象. 仅此而已, 它并不会对原来的实参有什么影响。
2.7 若向形参所指对象发送消息的话,可能出现什么结果?
形参所指对象实际上就是实参所指对象. 若该对象接到消息时状态发生变化的话,将会影响到主调方。请参考破坏性的方法。
2.8 参数前面的*是什么意思?
各位C语言大侠请看好, 这可不是什么指针。在Ruby的参数前面添加一个*表示, 它可以接受以数组形式传来的不定量的参数。
def foo(*all)
for e in all
print e, " "
end
end
foo(1, 2, 3)
#=> 1 2 3
另外,如果在方法调用中传了一个带*的数组, 则表示先展开数组然后再进行传递。
a = [1, 2, 3]
foo(*a)
现在只能在以下部分的尾部使用*
1. 多重赋值的左边
2. 多重赋值的右边
3. 参数列表(定义方法时)
4. 参数列表(调用方法时)
5. case的when部分
下面是在第(1)种形式中使用*的例子
x, *y = [7, 8, 9]
上面的代码相当于x = 7、y = [8, 9]。另外,下面的代码
x, = [7, 8, 9]
也是合法的, 此时x = 7. 而
x = [7, 8, 9]
则表示x = [7, 8, 9]。
2.9 参数前面的&代表什么?
在参数前面添加&之后,就可以像使用块那样来传递/接收过程对象。它只能位于参数列表的末尾。
2.10 可以给形参指定默认值吗?
可以。
在调用函数时,才会计算该默认值。您可以使用任意表达式来设定Ruby的默认值(C++只能使用编译时的常数). 调用方法时,会在方法的作用域内计算默认值。
2.11 如何向块传递参数呢?
在块内部的前端,使用||将形参括起来之后, 就可以使用实参进行多重赋值了。该形参只是普通的局部变量, 若块的外侧已经有同名参数时, 块参数的作用域将扩大到块外侧, 请留意这个问题。
2.12 为什么变量和常数的值会自己发生变化?
请看下例。
A = a = b = "abc"; b << "d"; print a, " ", A
#=> abcd abcd
对变量或常数进行赋值, 是为了以后通过它们来使用对象。这并不是将对象本身赋值给变量或常数, 而只是让它们记住对该对象的引用。变量可以修改这个引用来指向其他的对象, 而常数却不能修改引用。
对变量或常数使用方法时, 实际上就是对它们所指的对象使用该方法。在上例中, <<方法修改了对象的状态,所以引发了"非预期"的结果。若该对象是数值的话, 就不会发生这种问题, 因为数值没有修改其自身状态的方法。若对数值使用方法时, 将返回新的对象。
这个例子虽然是用字符串来作演示的, 但就算使用带有可修改自身状态的方法的那些对象, 如数组或哈希表等来试验的话, 效果也是一样的。
2.13 常数不能被修改吗?
若想让指向某对象的常数转而指向其他对象时, 就会出现warning。
若该对象带有破坏性的方法的话, 则可以修改该对象的内容。
3. 带块的方法调用
* 3.1 什么是"带块的方法调用"?
* 3.2 怎么将块传递给带块方法?
* 3.3 如何在主调方法中使用块?
* 3.4 为什么Proc.new没有生成过程对象呢?
3.1 什么是"带块的方法调用"?
有些方法允许在调用它的过程中添加块或者过程对象, 这种特殊的方法调用就是"带块的方法调用"。
这原本是为了对控制结构(特别是循环)进行抽象而设置的功能, 因此有时也被称作迭代器. 当然了, 若您只想调用块而不进行iterate(迭代)操作时,也可以使用它.
下例中就用到了迭代器。
data = [1, 2, 3]
data.each do |i|
print i, "\n"
end
它会输出如下内容。
$ ruby test.rb
1
2
3
也就是说,do和end之间的块被传递给方法, 供其差遣。each方法分别为data中的每个元素来执行块的内容。
用C语言来改写的话,就是
int data[3] = {1, 2, 3};
int i;
for (i = 0; i < 3; i++) {
printf("%d\n", data[i]);
}
用for来编写代码时, 必须自己进行迭代处理. 相反地, 使用带块的方法调用时, 则由方法负责处理, 这大大减少了因误判循环边界而导致bug的可能性。
另外, 除了do...end之外, 您还可以使用{...}。
data = [1, 2, 3]
data.each { |i|
print i, "\n"
}
这段代码与前面的完全等效。但这并不标明do...end与{...}完全等效。例如
foobar a, b do .. end # 此时foobar被看做是带块的方法
foobar a, b { .. } # 而此时 b被看做是带块的方法
这说明{ }的结合力大于do块。
3.2 怎么将块传递给带块方法?
如果想将块传递给带块方法, 只需要将块放在方法后面即可. 另外, 还可以在表示过程对象的变量/常数前添加&, 并将其作为参数传递给方法即可。
3.3 如何在主调方法中使用块?
有3种方式可以让您在方法中使用块. 它们分别是yield控制结构、块参数和Proc.new。(在由C语言写成的扩展库中,需要使用rb_yield)
使用yield时, yield后面的参数会被传递给块, 然后执行块的内容。
块参数是指,插在方法定义中的参数列表末尾的 形如&method的参数. 可以在方法中,这样method.call(args...)来进行调用。
使用Proc.new时, 它会接管传递给方法的块, 并以块的内容为范本生成一个过程对象。proc或lamda也是一样。
def a (&b)
yield
b.call
Proc.new.call
proc.call
lambda.call
end
a{print "test\n"}
3.4 为什么Proc.new没有生成过程对象呢?
若没有给出块的话, Proc.new是不会生成过程对象的, 而且还会引发错误。在方法定义中插入Proc.new时, 一般都假定在方法调用时会传过来一个块。
4. 句法
* 4.1 像:exit这种带:的标识符表示什么?
* 4.2 如何取得与符号同名的变量的值?
* 4.3 loop是控制结构吗?
* 4.4 a +b报错,这是怎么回事儿?
* 4.5 s = "x"; puts s *10 报错,这是怎么回事儿?
* 4.6 为什么p {}没有任何显示呢?
* 4.7 明明有pos=()这样的setter方法,可为什么pos=1时却没有任何反应呢?
* 4.8 '\1'和'\\1'有什么不同?
* 4.9 在p true or true and false中会显示true,但在a=true if true or true and false中却不会把true赋值给a。
* 4.10 为什么p(nil || "")什么事儿都没有,可p(nil or "")却会报错呢?
4.1 像:exit这种带:的标识符表示什么?
它叫做符号对象,它与标识符之间是1对1的关系。您也可以使用"exit".intern来得到它。在catch, throw, autoload等方法中,既可以使用字符串参数,又可以使用符号参数。
4.2 如何取得与符号同名的变量的值?
在symbol的作用域内,使用eval((:symbol).id2name)来取值。
a = 'This is the content of "a"'
b = eval(:a.id2name)
a.id == b.id
4.3 loop是控制结构吗?
不,它是方法。该块会导入新的局部变量的作用域。
4.4 a +b报错,这是怎么回事儿?
它会被解释成a(+b)。+的两侧要么都有空格,要么就都没有。
4.5 s = "x"; puts s *10 报错,这是怎么回事儿?
puts s *10会被解释成s(*10)的方法调用,所以要么s*10这样,要么s * 10这样。
4.6 为什么p {}没有任何显示呢?
{}会被解释成块,而并非哈希表的构造函数。所以您需要使用p({})或者p Hash.new来解决这个问题。
4.7 明明有pos=()这样的setter方法,可为什么pos=1时却没有任何反应呢?
请看下例。
class C
attr_reader :pos
def pos=(n)
@pos = n * 3
end
def set
pos = 1 #A行
end
end
a = C.new
a.set
p a.pos #=> nil (预期值是 3)
本来指望最后一行能输出 3,但却是个 nil ,这是因为Ruby把A行的pos解释成局部变量了。若想调用pos=()的话,请这样self.pos = 1调用。
4.8 '\1'和'\\1'有什么不同?
没有不同,二者完全一样。在单引号中,只有\'、\\和行尾的\(取消换行)会得到特殊的解释,其他字符不变。
4.9 在p true or true and false中会显示true,但在a=true if true or true and false中却不会把true赋值给a。
第1个表达式会被解释成(p true) or true and false,其中的and/or是构成语句的要素,而并不是用来连接p的参数的操作符。
第2个表达是则会被解释成a=true if (true or true and false)。因为if的优先度低于and/or,且or与and的优先度相同,所以就会从左到右地完成解析。
4.10 为什么p(nil || "")什么事儿都没有,可p(nil or "")却会报错呢?
虽然||可以连接参数,但or就只能连接句子,所以如此。关于这点区别,您试一试下面的例子就明白了。
p nil || ""
p nil or ""
5. 方法
* 5.1 向对象发出消息之后,将按照什么顺序来搜索要执行的方法?
* 5.2 +和-是操作符吗?
* 5.3 Ruby中有函数吗?
* 5.4可以在外部使用对象的实例变量吗?
* 5.5 private和protected有什么不同?
* 5.6 能不能将实例变量变成public类型的变量?
* 5.7 怎样指定方法的可见性?
* 5.8 方法名可以用大写字母开头吗?
* 5.9 为什么使用super时会出现ArgumentError?
* 5.10 如何调用上2层的同名方法?
* 5.11 重定义内部函数时,如何调用原来的函数?
* 5.12 何谓破环性的方法?
* 5.13 那些情况下会产生副作用?
* 5.14 能让方法返回多个值吗?
5.1 向对象发出消息之后,将按照什么顺序来搜索要执行的方法?
将依次搜索特殊方法、本类中定义的方法和超类(包括Mix-in进来的模块。写成 类名.ancestors。)中定义的方法,并执行所找到的第一个方法。若没有找到方法时,将按照同样的顺序来搜索method_missing。
module Indexed
def [](n)
to_a[n]
end
end
class String
include Indexed
end
p String.ancestors # [String, Indexed, Enumerable, Comparable, Object, Kernel]
p "abcde".gsub!(/./, "\\&\n")[1]
遗憾的是上述代码返回的是10,而并非预期的"b\n"。这是因为系统在String类中搜索[],在遇到Indexed中定义的方法之前就已经完成了匹配,所以如此。若直接在Class String中重定义[]的话,就会如您所愿了。
5.2 +和-是操作符吗?
+和-等是方法调用,而并非操作符。因此可进行overload(重定义)。
class MyString < String
def +(other)
print super(other)
end
end
但以下内容及其组合(!=、!~)则是控制结构,不能进行重定义。
=, .., ..., !, not, &&, and, |, or, ~, ::
重定义(或者定义)操作符时,应该使用形如+@或-@这样的方法名。
=是访问实例变量的方法,您可以在类定义中使用它来定义方法。另外,+或-等经过适当的定义之后,也可以进行形如+=这样的自赋值运算。
def attribute=(val)
@attribute = val
end
5.3 Ruby中有函数吗?
Ruby中看似函数的部分实际上都是些省略被调(self)的方法而已。例如
def writeln(str)
print(str, "\n")
end
writeln("Hello, World!")
中看似函数的部分实际上是Object类中定义的方法,它会被发送到隐藏的被调self中。因此可以说Ruby是纯粹的面向对象语言。
对内部函数这种方法来说,不管self如何,它们总是返回相同的结果。因此没有必要计较被调的问题,可以将其看作函数。
5.4 可以在外部使用对象的实例变量吗?
不能直接使用。若想操作实例变量,必须事先在对象中定义操作实例变量的方法(accessor)。例如
class C
def name
@name
end
def name=(str) # name 后面不能有空格!
@name = str
end
end
c = C.new
c.name = '山田太郎'
p c.name #=> "山田太郎"
另外,您还可以使用Module#attr、attr_reader、 attr_writer、attr_accessor等来完成这种简单的方法定义。例如,您可以这样来重写上面的类定义。
class C
attr_accessor :name
end
若您不愿定义访问方法,却想使用实例变量时,可以使用Object#instance_eval。
5.5 private和protected有什么不同?
private意味着只能使用函数形式来调用该方法,而不能使用被调形式。所以,您只能在本类或其子类中调用private方法。
protected也是一样,只能用在本类及其子类中。但是您既可以使用函数形式又可以使用被调形式来调用它。
在封装方法时,该功能是必不可少。
5.6 能不能将实例变量变成public类型的变量?
无法让变量变成public类型的变量。在Ruby中访问实例变量时,需要使用访问方法。例如
class Foo
def initialize(str)
@name = str
end
def name
return @name
end
end
但是每次都这么写的话,未免有些繁琐。因此可以使用attr_reader、attr_writer、 attr_accessor等方法来完成这些简单的方法定义。
class Foo
def initialize(str)
@name = str
end
attr_reader :name
# 其效果等同于下面的代码。
# def name
# return @name
# end
end
foo = Foo.new("Tom")
print foo.name, "\n" # Tom
您还可以使用attr_accessor来同时定义写入的方法。
class Foo
def initialize(str)
@name = str
end
attr_accessor :name
# 其效果等同于下面的代码。
# def name
# return @name
# end
# def name=(str)
# @name = str
# end
end
foo = Foo.new("Tom")
foo.name = "Jim"
print foo.name, "\n" # Jim
若只想定义写入方法的话,可以使用attr_writer。
5.7 怎样指定方法的可见性?
首先 Ruby把那些只能以函数形式(省略被调的形式)来调用的方法叫做private方法。请注意,这里的private定义与C++以及Java中的定义不同。
若将方法设为private类型之后,就不能在其它的对象中调用该方法了。因此,若您只想在本类或其子类中调用某方法时, 就可以把它设为private类型。
您可以这样把方法设为private类型。
class Foo
def test
print "hello\n"
end
private :test
end
foo = Foo.new
foo.test
#=> test.rb:9: private method `test' called for #<Foo:0x400f3eec>(Foo)
您可以使用private_class_method将类方法变为private类型。
class Foo
def Foo.test
print "hello\n"
end
private_class_method :test
end
Foo.test
#=> test.rb:8: private method `test' called for Foo(Class)
同理,您可以使用public、public_class_method将方法设为public类型。
在默认情况下,类中的方法都被定义成public类型(initialize除外),而顶层中的方法会被定义成private类型。
5.8 方法名可以用大写字母开头吗?
可以。但要注意:即使方法调用中不带参数,也不能省略方法名后的空括号。
5.9 为什么使用super时会出现ArgumentError?
在方法定义中调用super时,会把所有参数都传给上层方法,若参数个数不符合其要求,就会引发ArgumentError。因此,若参数个数不合时,应该自己指定参数然后再调用super。
5.10 如何调用上2层的同名方法?
super只能调用上1层的同名方法。若想调用2层以上的同名方法时,需要事先对该上层方法进行alias操作。
5.11 重定义内部函数时,如何调用原来的函数?
可以在方法定义中使用super。进行重定义之前,使用alias就可以保住原来的定义。也可以把它当作Kernel的特殊方法来进行调用。
5.12 何谓破环性的方法?
就是能修改对象内容的方法,常见于字符串、数组或哈希表中。一般是这样的:存在两个同名的方法,一个会拷贝原对象并返回副本;一个会直接修改原对象的内容,并返回修改后的对象。通常后者的方法名后面带有!,它就是破坏性的方法。但是有些不带!的方法也是具有破环性的,如String#concat等等。
5.13 那些情况下会产生副作用?
若在方法中对实参对象使用了破环性的方法的时候,就会产生副作用。
def foo(str)
str.sub!(/foo/, "baz")
end
obj = "foo"
foo(obj)
print obj
#=> "baz"
此时,参数对象的内容被修改。另一方面,如果在程序中确有必要的话,也会对某对象发送具有副作用的消息,那就另当别论了。
5.14 能让方法返回多个值吗?
在Ruby中确实只能指定一个方法返回值,但若使用数组的话,就可以返回多个值了。
return 1, 2, 3
上例中,传给return的列表会被当作数组处理。这与下面的代码可谓是异曲同工。
return [1, 2, 3]
另外,若使用多重赋值的话,则可以达到返回多个值的效果。例如
def foo
return 20, 4, 17
end
a, b, c = foo
print "a:", a, "\n" #=> a:20
print "b:", b, "\n" #=> b:4
print "c:", c, "\n" #=> c:17
您也可以这样处理。
1. 一般的问题
2. 变量、常数、参数
3. 调用带块方法(迭代器)
4. 句法
5. 方法
6. 类、模块
7. 内部库
8. 扩展库
9. 尚未列出的功能
10. 日语字符的处理
11. Ruby的处理系统
一般的问题
* 1.1 Ruby是什么?
* 1.2 为什么取名叫Ruby呢?
* 1.3 请介绍一下Ruby的诞生过程
* 1.4 哪里有Ruby的安装文件?
* 1.5 请问Ruby的主页在哪里?
* 1.6 请问有Ruby邮件列表吗?
* 1.7 怎么才能看到邮件列表中的老邮件?
* 1.8 rubyist和ruby hacker的区别是什么?
* 1.9 它的正确写法是"Ruby"还是"ruby"?
* 1.10 请介绍一些Ruby的参考书
* 1.11 我看了手册可还是不明白,该怎么办?
* 1.12 ruby的性格比较像羊?
* 1.13 遇到bug时怎么上报?
变量、常数、参数
* 2.1 将对象赋值给变量或常数时,会先拷贝该对象吗?
* 2.2 局部变量的作用域是如何划定的?
* 2.3 何时才能使用局部变量?
* 2.4 常数的作用域是如何划定的?
* 2.5 实参是怎么传递给形参的呢?
* 2.6 将实参赋值给形参之后,对实参本身有什么影响吗?
* 2.7 若向形参所指对象发送消息的话,可能出现什么结果?
* 2.8 参数前面的*是什么意思?
* 2.9 参数前面的&代表什么?
* 2.10 可以给形参指定默认值吗?
* 2.11 如何向块传递参数呢?
* 2.12 为什么变量和常数的值会自己发生变化?
* 2.13 常数不能被修改吗?
调用带块方法
* 3.1 什么是"带块的方法调用"?
* 3.2 怎么将块传递给带块方法?
* 3.3 如何在主调方法中使用块?
* 3.4 为什么Proc.new没有生成过程对象呢?
句法
* 4.1 像:exit这种带:的标识符表示什么?
* 4.2 如何取得与符号同名的变量的值?
* 4.3 loop是控制结构吗?
* 4.4 a +b报错,这是怎么回事儿?
* 4.5 s = "x"; puts s *10 报错,这是怎么回事儿?
* 4.6 为什么p {}没有任何显示呢?
* 4.7 明明有pos=()这样的setter方法,可为什么pos=1时却没有任何反应呢?
* 4.8 '\1'和'\\1'有什么不同?
* 4.9 在p true or true and false中会显示true,但在a=true if true or true and false中却不会把true赋值给a。
* 4.10 为什么p(nil || "")什么事儿都没有,可p(nil or "")却会报错呢?
方法
* 5.1 向对象发出消息之后,将按照什么顺序来搜索要执行的方法?
* 5.2 +和-是操作符吗?
* 5.3 Ruby中有函数吗?
* 5.4可以在外部使用对象的实例变量吗?
* 5.5 private和protected有什么不同?
* 5.6 能不能将实例变量变成public类型的变量?
* 5.7 怎样指定方法的可见性?
* 5.8 方法名可以用大写字母开头吗?
* 5.9 为什么使用super时会出现ArgumentError?
* 5.10 如何调用上2层的同名方法?
* 5.11 重定义内部函数时,如何调用原来的函数?
* 5.12 何谓破环性的方法?
* 5.13 那些情况下会产生副作用?
* 5.14 能让方法返回多个值吗?
类、模块
* 6.1 重定义类时,是否会覆盖原来的定义?
* 6.2 有类变量吗?
* 6.3 什么是类的实例变量?
* 6.4 什么是特殊方法?
* 6.5 什么是类方法?
* 6.6 什么是特殊类?
* 6.7 什么是模块函数?
* 6.8 类和模块有什么区别?
* 6.9 模块可以生成子类吗?
* 6.10 在类定义中定义类方法 和 在顶层中定义类方法 之间有什么不同?
* 6.11 load和require有什么不同?
* 6.12 include和extend有什么不同?
* 6.13 self是什么?
* 6.14 MatchData中的begin、end分别返回什么?
* 6.15 如何使用类名来获得类?
内部库
* 7.1 instance_methods(true)返回什么?
* 7.2 为什么rand总是生成相同的随机数?
* 7.3 怎样从0到51中选出5个不重复的随机数呢?
* 7.4 Fixnum、Symbol、true、nil和false这些立即值与引用有什么不同?
* 7.5 nil和false有什么不同?
* 7.6 为什么读入文件并修改之后, 原文件依然没有变化?
* 7.7 怎样覆盖同名文件?
* 7.8 写文件后拷贝该文件,但所得副本并不完整,请问原因何在?
* 7.9 在管道中将字符串传给less后, 为什么看不到结果?
* 7.10 无法引用的File对象将会何去何从?
* 7.11 怎样手动关闭文件?
* 7.12 如何按照更新时间的新旧顺序来排列文件?
* 7.13 如何获取文件中单词的出现频度?
* 7.14 为什么条件表达式中的空字符串表示true呢?
* 7.15 如何按照字典顺序来排列英文字符串数组?
* 7.16 "abcd"[0]会返回什么?
* 7.17 怎么把tab变成space?
* 7.18 如何对反斜线进行转义操作?
* 7.19 sub和sub!的区别在哪里?
* 7.20 \Z匹配什么?
* 7.21 范围对象中的..和...有什么不同?
* 7.22 有函数指针吗?
* 7.23 线程和进程fork有何异同?
* 7.24 如何使用Marshal?
* 7.25 Ruby有异常处理语句吗?
* 7.26 如何使用trap?
* 7.27 如何统计文件的行数?
* 7.28 怎样把数组转化为哈希表?
* 7.29 将字符串变为Array时可以使用%w(...),那么将字符串变为Hash时能不能如法炮制呢?
* 7.30 为何无法捕捉NameError异常呢?
* 7.31 为什么有succ却没有prev呢
扩展库
* 8.1 如何使用交互式Ruby?
* 8.2 有调试器吗?
* 8.3 怎样在Ruby中使用以C写成的库?
* 8.4 有Tcl/Tk的接口吗?
* 8.5 为什么我的Tk不管用?
* 8.6 有gtk+、xforms的接口吗?
* 8.7 进行日期计算时需要注意哪些问题?
尚未列出的功能
日语字符的处理
* 10.1 若包含汉字的脚本输出乱码或无法正常运行时,该如何处理?
* 10.2 选项-K和$KCODE有什么不同?
* 10.3 可以使用日语标识符吗?
* 10.4 如何从包含日语字符的字符串中依次抽出1个字符?
* 10.5 tr("あ","a")运作不正常,应如何处置?
* 10.6 如何对平假名进行排序?
* 10.7 如何用空白来替代SJIS中从84BF到889F之间的系统相关代码?
* 10.8 如何进行全角-半角字符的变换?
* 10.9 关于半角假名的问题
* 10.10 怎样从包含日语字符的字符串中抽出n字节的内容?
* 10.11 怎么让日语文本在第n个字处换行?
Ruby的处理系统
* 11.1 能不能编译Ruby脚本呢?
* 11.2 有没有Java VM版的Ruby?
* 11.3 除了original Ruby之外,就没有其他版本吗?
* 11.4 有没有Ruby用的indent?
* 11.5 有没有使用本地线程的Ruby?
* 11.6 GC实在是太慢了,怎么办才好?
* 11.7 有没有Mac版的Ruby?
1. 一般的问题
* 1.1 Ruby是什么?
* 1.2 为什么取名叫Ruby呢?
* 1.3 请介绍一下Ruby的诞生过程
* 1.4 哪里有Ruby的安装文件?
* 1.5 请问Ruby的主页在哪里?
* 1.6 请问有Ruby邮件列表吗?
* 1.7 怎么才能看到邮件列表中的老邮件?
* 1.8 rubyist和ruby hacker的区别是什么?
* 1.9 它的正确写法是"Ruby"还是"ruby"?
* 1.10 请介绍一些Ruby的参考书
* 1.11 我看了手册可还是不明白,该怎么办?
* 1.12 ruby的性格比较像羊?
* 1.13 遇到bug时怎么上报?
1.1 Ruby是什么?
一言以蔽之,Ruby是一种
语法简单且功能强大的面向对象的脚本语言。
与perl一样,Ruby的文本处理功能十分强大。当然了它的功能远不止于此,您还可以使用它来开发实用的服务器软件。
Ruby博采众长,吸收了众多语言的优点,却又别具一格。
Ruby的优点主要体现在以下几个方面。
* 它的语法简单
* 它具有普通的面向对象功能(类、方法调用等)
* 它还具有特殊的面向对象功能(Mix-in、特殊方法等)
* 可重载操作符
* 具有异常处理功能
* 调用带块方法(迭代器)和闭包
* 垃圾回收器
* 动态载入(取决于系统架构)
* 可移植性。它可以运行在大部分的UNIX、DOS和Mac上
1.2 为什么取名叫Ruby呢?
松本先生曾经在[ruby-talk:00394][英译稿](June 11, 1999)中讲过取名的经过。
据说当初松本先生一直琢磨着要给这个新语言取个像Perl这样的宝石名字,正好有个同事的诞生石是Ruby,因此就取名叫Ruby了。
后来发现Ruby和Perl真的很投缘,例如pearl诞生石代表6月,而ruby诞生石则代表7月。还有pearl的字体大小是5pt,而ruby则是5.5pt等等。因此松本先生觉得Ruby这个名字很合适,并努力使其成为比Perl更新更好的脚本语言。
松本先生正期待着Ruby取代Perl的那一天早点到来(^^)。
1.3 请介绍一下Ruby的诞生过程
松本先生曾经在[ruby-talk:00382][英译稿](June 4, 1999)中介绍过Ruby的诞生过程。[ruby-list:15997]修改了Ruby的诞生时间。
*
Ruby诞生于1993年2月24日。那天我和同事们聊了聊面向对象语言的可能性问题。我了解Perl(Perl4而非Perl5),但我不喜欢它身上的那股玩具味儿(现在也是如此)。面向对象的脚本语言的前途一片光明。
我觉得Python不能算作真正的面向对象语言,因为它的面向对象特性好像是后加进去的一样。15年来我一直为编程语言而痴狂,我热衷于面向对象编程,但却没有找到一款真正意义上的面向对象的脚本语言。
于是我下定决心自己来开发一个。经过几个月的努力,解释器终于开发成功。然后我又添加了一些自己梦寐以求的东西,如迭代器、异常处理、垃圾回收等。
后来我又采用类库方式添加了Perl的特性。1995年12月,我在日本国内的新闻组上发布了Ruby 0.95版本。
接下来我创建了邮件列表和网站。此后,大家在邮件列表中聊得酣畅淋漓。时至今日,第一个邮件列表中已经积累了14789封邮件。
Ruby 1.0发布于1996年12月,1.1发布于1997年8月。1998年12月,我又发布了安定版1.2和开发版1.3。
1.4 哪里有Ruby的安装文件?
您可以在这里<URL:ftp://ftp.ruby-lang.org/pub/ruby/>找到最新版的Ruby。
镜像站点列表如下
* <URL:ftp://ftp.TokyoNet.AD.JP/pub/misc/ruby/>
* <URL:ftp://ftp.iij.ad.jp/pub/lang/ruby/>
* <URL:ftp://blade.nagaokaut.ac.jp/pub/lang/ruby/>
* <URL:ftp://ftp.krnet.ne.jp/pub/ruby/>
* <URL:ftp://mirror.nucba.ac.jp/mirror/ruby/>
* <URL:http://mirror.nucba.ac.jp/mirror/ruby/>
您可以在Ruby Binaries中找到cygwin版、mingw版和djgpp版的二进制文件包。
另外,Windows(cygwin)中还为初学者准备了Ruby Entry Package。安装方法请参考面向初学者的Ruby安装说明。
1.5 请问Ruby的主页在哪里?
Ruby的官方网站是<URL:http://www.ruby-lang.org/>。
1.6 请问有Ruby邮件列表吗?
现在有6个正式的Ruby邮件列表。
* ruby-list
* ruby-dev
* ruby-ext
* ruby-math
* ruby-talk
* ruby-core
详情请参考Ruby邮件列表。
1.7 怎么才能看到邮件列表中的老邮件?
<URL:http://blade.nagaokaut.ac.jp/ruby/ruby-list/index.shtml>和<URL:http://ruby.freak.ne.jp/>里面有搜索邮件用的表单。
另外,ML Topics中列出了老邮件中的重要话题。
1.8 rubyist和ruby hacker的区别是什么?
松本先生对rubyist和Ruby hacker的定义如下。
rubyist是指那些对Ruby的关心程度超过常人的人。例如
* 向周围的人宣传Ruby的人
* 编写Ruby的FAQ的人
* 在计算机通信组中增加Ruby小组的组长
* 撰写Ruby书籍的作者
* 写信鼓励Ruby作者的热心人
* Ruby作者本人 ^^;;;
而Ruby hacker是指那些在技术层面上对Ruby有所专攻的人。例如
* Ruby扩展库的作者
* 修改Ruby中的bug并发布补丁的人
* djgpp版Ruby或win32版Ruby的作者
* 用Ruby编写了实用(必须得具备一定规模的)程序的人
* 用Ruby编写出天书般难懂的脚本的人
* Ruby作者本人 ^^;;;
等就是Ruby hacker。
这些称号只不过是自我解嘲式的自称,我不会为任何人进行正式的认证。松本先生特别将上述人士列为{rubyist、Ruby hacker},可见其尊敬之情。
1.9 它的正确写法是"Ruby"还是"ruby"?
Ruby的正式写法是"Ruby",其命令名是"ruby"。另外只要不让人觉得别扭的话,也可以使用ruby来替代Ruby。
但不能把"RUBY"、"ルビー"或"るびー"用作这门语言的名称。
此前曾经有一段时间把"ruby"用作正式名称。
1.10 请介绍一些Ruby的参考书
主要有《オブジェクト指向スクリプト言語Ruby》(译注:日语书名未翻译)[松本行弘/石塚圭树 合著 ASCII出版(ISBN4-7561-3254-5)],其他书目请参考Ruby相关书籍。
至于正则表达式,请参考Jeffrey E. F.Friedl著的《詳説正規表現》(译注:日语书名未翻译)[reilly Japan出版(ISBN4-900900-45-1)]。这本书介绍了各种正则表达式的实现问题,有助于加深您对于Ruby正则表达式的理解。
1.11 我看了手册可还是不明白,该怎么办?
Ruby的基本句法从Ruby1.0以后就没有太大的变化,但却在不断完善和扩充,因此有时文档的更新速度跟不上最新的发展。另外,有人坚持说源代码就是文档,如此种种。
若您有何疑问,请不必顾虑太多,直接到ruby-list中提问即可。Ruby教主松本先生以及各位尊师还有我都会为您排忧解难。
提问时,请写明ruby -v的结果并附带上您的代码(若代码太长的话,只需摘录重要部分即可)。
若您使用的是irb的话,则稍有不同。因为irb自身也存在一些问题,所以您最好先用irb --single-irb重试一下,或者用ruby重新运行一次为好。
虽然搜索ML可以解决您的大部分问题,但因为邮件数量庞大,想找到答案实属不易。为遵从网络礼节(请参考RFC1855的3.1.1、3.1.2),您可以只搜索最近的内容,但是说起来容易,做起来难。况且说不定最近又出现了什么新观点呢。所以您还是壮起胆子来提问吧。
1.12 ruby的性格比较像羊?
羊、蜂鸟、兔子...
1.13 遇到bug时怎么上报?
遇到bug时应该上报到Ruby Bug Tracking System,通常很快就会得到回复。您也可以用邮件将bug的情况上报到ruby-bugs-ja。
上报时,最好能提供ruby的版本和平台信息、错误消息以及能再现bug的脚本和数据。
遇到bug时,通常会显示[BUG]消息,而Ruby也将被强行关闭。此时大部分系统都会生成一个core文件。若您的调试器可用的话,可能还会有backtrace。若您能提供这些信息就更好了。
2. 变量、常数、参数
* 2.1 将对象赋值给变量或常数时,会先拷贝该对象吗?
* 2.2 局部变量的作用域是如何划定的?
* 2.3 何时才能使用局部变量?
* 2.4 常数的作用域是如何划定的?
* 2.5 实参是怎么传递给形参的呢?
* 2.6 将实参赋值给形参之后,对实参本身有什么影响吗?
* 2.7 若向形参所指对象发送消息的话,可能出现什么结果?
* 2.8 参数前面的*是什么意思?
* 2.9 参数前面的&代表什么?
* 2.10 可以给形参指定默认值吗?
* 2.11 如何向块传递参数呢?
* 2.12 为什么变量和常数的值会自己发生变化?
* 2.13 常数不能被修改吗?
2.1 将对象赋值给变量或常数时,会先拷贝该对象吗?
变量和常数都指向一个对象。即使不赋值, 它也是指向nil对象的。赋值操作只不过是让它指向另一个新对象而已。
所以, 赋值时并不会拷贝并生成一个新对象. 而是让赋值表达式左边的变量或常数指向表达式右边的对象。
尽管如此, 可能还是有人不理解. 这也是情有可原的, 因为上面的解释并不能涵盖所有的情况. 实际上, Fixnum、NilClass、 TrueClass、FalseClass以及Symbol类的实例会被变量或常数直接保存, 所以赋值时会被拷贝。其他类的实例都在内存上的其他地方, 变量和常数会指向它们。请参考立即值和使用。
2.2 局部变量的作用域是如何划定的?
顶层、类(模块)定义或方法定义都是彼此独立的作用域。另外, 在块导入新的作用域时, 它还可以使用外侧的局部变量。
块之所以与众不同, 是因为这样能够保证Thread或过程对象中的局部变量的"局部性"。while、until、for是控制结构, 它们不会导入新的作用域。另外, loop是方法, 它的后面跟着块。
2.3 何时才能使用局部变量?
在Ruby解释器运行Ruby脚本时, 它会一次读取整个脚本,然后进行语法分析。若没有语法问题的话, 才会开始执行句法分析中得到的代码。
在进行语法分析时, 只有在遇到局部变量的赋值语句之后, 才能使用它。例如
for i in 1..2
if i == 2
print a
else
a = 1
end
end
把上述代码写入名为test.rb的脚本. 执行该脚本后发生如下错误
test.rb:3: undefined local variable or method `a' for
#<Object:0x40101f4c> (NameError)
from test.rb:1:in `each'
from test.rb:1
当i值为1时,并不会发生错误;当i变成2之后就不行了。这是因为, 在进行语法分析时并不会按照运行时的逻辑顺序来进行, 而只是机械地逐行分析. 在遇到print a语句时, a并未被赋值, 因而无法使用该局部变量. 之后,在运行时因为找不到名为a的方法, 所以发生错误。
相反地, 若使用如下脚本则不会出现错误。
a = 1 if false; print a
#=> nil
若您不想因为局部变量的这个特性而费神的话, 我们推荐您在使用局部变量之前, 添加a = nil赋值语句。这样作还有一个好处, 就是可以加快局部变量的使用速度。
2.4 常数的作用域是如何划定的?
类/模块中定义的常数可以用在该类/模块中。
若类/模块定义发生嵌套时, 可在内侧类/模块中使用外侧的常数。
还可以使用超类以及包含模块中的常数。
因为顶层中定义的常数已经被添加到Object类中, 所以您可以在所有的类/模块中使用顶层中的常数。
若遇到无法直接使用的常数时, 可以使用 类/模块名+::操作符+常数名 的方式来使用它。
2.5 实参是怎么传递给形参的呢?
方法调用时, 会把实参赋值给形参。请您参考向变量进行赋值来了解Ruby中赋值的含义。若实参中的对象包含可以改变自身状态的方法时,就必须注意其副作用(当然了,也有可能不是副作用)了。请参考破坏性的方法。
2.6 将实参赋值给形参之后,对实参本身有什么影响吗?
形参是局部变量, 对其进行赋值之后, 它就会指向其他对象. 仅此而已, 它并不会对原来的实参有什么影响。
2.7 若向形参所指对象发送消息的话,可能出现什么结果?
形参所指对象实际上就是实参所指对象. 若该对象接到消息时状态发生变化的话,将会影响到主调方。请参考破坏性的方法。
2.8 参数前面的*是什么意思?
各位C语言大侠请看好, 这可不是什么指针。在Ruby的参数前面添加一个*表示, 它可以接受以数组形式传来的不定量的参数。
def foo(*all)
for e in all
print e, " "
end
end
foo(1, 2, 3)
#=> 1 2 3
另外,如果在方法调用中传了一个带*的数组, 则表示先展开数组然后再进行传递。
a = [1, 2, 3]
foo(*a)
现在只能在以下部分的尾部使用*
1. 多重赋值的左边
2. 多重赋值的右边
3. 参数列表(定义方法时)
4. 参数列表(调用方法时)
5. case的when部分
下面是在第(1)种形式中使用*的例子
x, *y = [7, 8, 9]
上面的代码相当于x = 7、y = [8, 9]。另外,下面的代码
x, = [7, 8, 9]
也是合法的, 此时x = 7. 而
x = [7, 8, 9]
则表示x = [7, 8, 9]。
2.9 参数前面的&代表什么?
在参数前面添加&之后,就可以像使用块那样来传递/接收过程对象。它只能位于参数列表的末尾。
2.10 可以给形参指定默认值吗?
可以。
在调用函数时,才会计算该默认值。您可以使用任意表达式来设定Ruby的默认值(C++只能使用编译时的常数). 调用方法时,会在方法的作用域内计算默认值。
2.11 如何向块传递参数呢?
在块内部的前端,使用||将形参括起来之后, 就可以使用实参进行多重赋值了。该形参只是普通的局部变量, 若块的外侧已经有同名参数时, 块参数的作用域将扩大到块外侧, 请留意这个问题。
2.12 为什么变量和常数的值会自己发生变化?
请看下例。
A = a = b = "abc"; b << "d"; print a, " ", A
#=> abcd abcd
对变量或常数进行赋值, 是为了以后通过它们来使用对象。这并不是将对象本身赋值给变量或常数, 而只是让它们记住对该对象的引用。变量可以修改这个引用来指向其他的对象, 而常数却不能修改引用。
对变量或常数使用方法时, 实际上就是对它们所指的对象使用该方法。在上例中, <<方法修改了对象的状态,所以引发了"非预期"的结果。若该对象是数值的话, 就不会发生这种问题, 因为数值没有修改其自身状态的方法。若对数值使用方法时, 将返回新的对象。
这个例子虽然是用字符串来作演示的, 但就算使用带有可修改自身状态的方法的那些对象, 如数组或哈希表等来试验的话, 效果也是一样的。
2.13 常数不能被修改吗?
若想让指向某对象的常数转而指向其他对象时, 就会出现warning。
若该对象带有破坏性的方法的话, 则可以修改该对象的内容。
3. 带块的方法调用
* 3.1 什么是"带块的方法调用"?
* 3.2 怎么将块传递给带块方法?
* 3.3 如何在主调方法中使用块?
* 3.4 为什么Proc.new没有生成过程对象呢?
3.1 什么是"带块的方法调用"?
有些方法允许在调用它的过程中添加块或者过程对象, 这种特殊的方法调用就是"带块的方法调用"。
这原本是为了对控制结构(特别是循环)进行抽象而设置的功能, 因此有时也被称作迭代器. 当然了, 若您只想调用块而不进行iterate(迭代)操作时,也可以使用它.
下例中就用到了迭代器。
data = [1, 2, 3]
data.each do |i|
print i, "\n"
end
它会输出如下内容。
$ ruby test.rb
1
2
3
也就是说,do和end之间的块被传递给方法, 供其差遣。each方法分别为data中的每个元素来执行块的内容。
用C语言来改写的话,就是
int data[3] = {1, 2, 3};
int i;
for (i = 0; i < 3; i++) {
printf("%d\n", data[i]);
}
用for来编写代码时, 必须自己进行迭代处理. 相反地, 使用带块的方法调用时, 则由方法负责处理, 这大大减少了因误判循环边界而导致bug的可能性。
另外, 除了do...end之外, 您还可以使用{...}。
data = [1, 2, 3]
data.each { |i|
print i, "\n"
}
这段代码与前面的完全等效。但这并不标明do...end与{...}完全等效。例如
foobar a, b do .. end # 此时foobar被看做是带块的方法
foobar a, b { .. } # 而此时 b被看做是带块的方法
这说明{ }的结合力大于do块。
3.2 怎么将块传递给带块方法?
如果想将块传递给带块方法, 只需要将块放在方法后面即可. 另外, 还可以在表示过程对象的变量/常数前添加&, 并将其作为参数传递给方法即可。
3.3 如何在主调方法中使用块?
有3种方式可以让您在方法中使用块. 它们分别是yield控制结构、块参数和Proc.new。(在由C语言写成的扩展库中,需要使用rb_yield)
使用yield时, yield后面的参数会被传递给块, 然后执行块的内容。
块参数是指,插在方法定义中的参数列表末尾的 形如&method的参数. 可以在方法中,这样method.call(args...)来进行调用。
使用Proc.new时, 它会接管传递给方法的块, 并以块的内容为范本生成一个过程对象。proc或lamda也是一样。
def a (&b)
yield
b.call
Proc.new.call
proc.call
lambda.call
end
a{print "test\n"}
3.4 为什么Proc.new没有生成过程对象呢?
若没有给出块的话, Proc.new是不会生成过程对象的, 而且还会引发错误。在方法定义中插入Proc.new时, 一般都假定在方法调用时会传过来一个块。
4. 句法
* 4.1 像:exit这种带:的标识符表示什么?
* 4.2 如何取得与符号同名的变量的值?
* 4.3 loop是控制结构吗?
* 4.4 a +b报错,这是怎么回事儿?
* 4.5 s = "x"; puts s *10 报错,这是怎么回事儿?
* 4.6 为什么p {}没有任何显示呢?
* 4.7 明明有pos=()这样的setter方法,可为什么pos=1时却没有任何反应呢?
* 4.8 '\1'和'\\1'有什么不同?
* 4.9 在p true or true and false中会显示true,但在a=true if true or true and false中却不会把true赋值给a。
* 4.10 为什么p(nil || "")什么事儿都没有,可p(nil or "")却会报错呢?
4.1 像:exit这种带:的标识符表示什么?
它叫做符号对象,它与标识符之间是1对1的关系。您也可以使用"exit".intern来得到它。在catch, throw, autoload等方法中,既可以使用字符串参数,又可以使用符号参数。
4.2 如何取得与符号同名的变量的值?
在symbol的作用域内,使用eval((:symbol).id2name)来取值。
a = 'This is the content of "a"'
b = eval(:a.id2name)
a.id == b.id
4.3 loop是控制结构吗?
不,它是方法。该块会导入新的局部变量的作用域。
4.4 a +b报错,这是怎么回事儿?
它会被解释成a(+b)。+的两侧要么都有空格,要么就都没有。
4.5 s = "x"; puts s *10 报错,这是怎么回事儿?
puts s *10会被解释成s(*10)的方法调用,所以要么s*10这样,要么s * 10这样。
4.6 为什么p {}没有任何显示呢?
{}会被解释成块,而并非哈希表的构造函数。所以您需要使用p({})或者p Hash.new来解决这个问题。
4.7 明明有pos=()这样的setter方法,可为什么pos=1时却没有任何反应呢?
请看下例。
class C
attr_reader :pos
def pos=(n)
@pos = n * 3
end
def set
pos = 1 #A行
end
end
a = C.new
a.set
p a.pos #=> nil (预期值是 3)
本来指望最后一行能输出 3,但却是个 nil ,这是因为Ruby把A行的pos解释成局部变量了。若想调用pos=()的话,请这样self.pos = 1调用。
4.8 '\1'和'\\1'有什么不同?
没有不同,二者完全一样。在单引号中,只有\'、\\和行尾的\(取消换行)会得到特殊的解释,其他字符不变。
4.9 在p true or true and false中会显示true,但在a=true if true or true and false中却不会把true赋值给a。
第1个表达式会被解释成(p true) or true and false,其中的and/or是构成语句的要素,而并不是用来连接p的参数的操作符。
第2个表达是则会被解释成a=true if (true or true and false)。因为if的优先度低于and/or,且or与and的优先度相同,所以就会从左到右地完成解析。
4.10 为什么p(nil || "")什么事儿都没有,可p(nil or "")却会报错呢?
虽然||可以连接参数,但or就只能连接句子,所以如此。关于这点区别,您试一试下面的例子就明白了。
p nil || ""
p nil or ""
5. 方法
* 5.1 向对象发出消息之后,将按照什么顺序来搜索要执行的方法?
* 5.2 +和-是操作符吗?
* 5.3 Ruby中有函数吗?
* 5.4可以在外部使用对象的实例变量吗?
* 5.5 private和protected有什么不同?
* 5.6 能不能将实例变量变成public类型的变量?
* 5.7 怎样指定方法的可见性?
* 5.8 方法名可以用大写字母开头吗?
* 5.9 为什么使用super时会出现ArgumentError?
* 5.10 如何调用上2层的同名方法?
* 5.11 重定义内部函数时,如何调用原来的函数?
* 5.12 何谓破环性的方法?
* 5.13 那些情况下会产生副作用?
* 5.14 能让方法返回多个值吗?
5.1 向对象发出消息之后,将按照什么顺序来搜索要执行的方法?
将依次搜索特殊方法、本类中定义的方法和超类(包括Mix-in进来的模块。写成 类名.ancestors。)中定义的方法,并执行所找到的第一个方法。若没有找到方法时,将按照同样的顺序来搜索method_missing。
module Indexed
def [](n)
to_a[n]
end
end
class String
include Indexed
end
p String.ancestors # [String, Indexed, Enumerable, Comparable, Object, Kernel]
p "abcde".gsub!(/./, "\\&\n")[1]
遗憾的是上述代码返回的是10,而并非预期的"b\n"。这是因为系统在String类中搜索[],在遇到Indexed中定义的方法之前就已经完成了匹配,所以如此。若直接在Class String中重定义[]的话,就会如您所愿了。
5.2 +和-是操作符吗?
+和-等是方法调用,而并非操作符。因此可进行overload(重定义)。
class MyString < String
def +(other)
print super(other)
end
end
但以下内容及其组合(!=、!~)则是控制结构,不能进行重定义。
=, .., ..., !, not, &&, and, |, or, ~, ::
重定义(或者定义)操作符时,应该使用形如+@或-@这样的方法名。
=是访问实例变量的方法,您可以在类定义中使用它来定义方法。另外,+或-等经过适当的定义之后,也可以进行形如+=这样的自赋值运算。
def attribute=(val)
@attribute = val
end
5.3 Ruby中有函数吗?
Ruby中看似函数的部分实际上都是些省略被调(self)的方法而已。例如
def writeln(str)
print(str, "\n")
end
writeln("Hello, World!")
中看似函数的部分实际上是Object类中定义的方法,它会被发送到隐藏的被调self中。因此可以说Ruby是纯粹的面向对象语言。
对内部函数这种方法来说,不管self如何,它们总是返回相同的结果。因此没有必要计较被调的问题,可以将其看作函数。
5.4 可以在外部使用对象的实例变量吗?
不能直接使用。若想操作实例变量,必须事先在对象中定义操作实例变量的方法(accessor)。例如
class C
def name
@name
end
def name=(str) # name 后面不能有空格!
@name = str
end
end
c = C.new
c.name = '山田太郎'
p c.name #=> "山田太郎"
另外,您还可以使用Module#attr、attr_reader、 attr_writer、attr_accessor等来完成这种简单的方法定义。例如,您可以这样来重写上面的类定义。
class C
attr_accessor :name
end
若您不愿定义访问方法,却想使用实例变量时,可以使用Object#instance_eval。
5.5 private和protected有什么不同?
private意味着只能使用函数形式来调用该方法,而不能使用被调形式。所以,您只能在本类或其子类中调用private方法。
protected也是一样,只能用在本类及其子类中。但是您既可以使用函数形式又可以使用被调形式来调用它。
在封装方法时,该功能是必不可少。
5.6 能不能将实例变量变成public类型的变量?
无法让变量变成public类型的变量。在Ruby中访问实例变量时,需要使用访问方法。例如
class Foo
def initialize(str)
@name = str
end
def name
return @name
end
end
但是每次都这么写的话,未免有些繁琐。因此可以使用attr_reader、attr_writer、 attr_accessor等方法来完成这些简单的方法定义。
class Foo
def initialize(str)
@name = str
end
attr_reader :name
# 其效果等同于下面的代码。
# def name
# return @name
# end
end
foo = Foo.new("Tom")
print foo.name, "\n" # Tom
您还可以使用attr_accessor来同时定义写入的方法。
class Foo
def initialize(str)
@name = str
end
attr_accessor :name
# 其效果等同于下面的代码。
# def name
# return @name
# end
# def name=(str)
# @name = str
# end
end
foo = Foo.new("Tom")
foo.name = "Jim"
print foo.name, "\n" # Jim
若只想定义写入方法的话,可以使用attr_writer。
5.7 怎样指定方法的可见性?
首先 Ruby把那些只能以函数形式(省略被调的形式)来调用的方法叫做private方法。请注意,这里的private定义与C++以及Java中的定义不同。
若将方法设为private类型之后,就不能在其它的对象中调用该方法了。因此,若您只想在本类或其子类中调用某方法时, 就可以把它设为private类型。
您可以这样把方法设为private类型。
class Foo
def test
print "hello\n"
end
private :test
end
foo = Foo.new
foo.test
#=> test.rb:9: private method `test' called for #<Foo:0x400f3eec>(Foo)
您可以使用private_class_method将类方法变为private类型。
class Foo
def Foo.test
print "hello\n"
end
private_class_method :test
end
Foo.test
#=> test.rb:8: private method `test' called for Foo(Class)
同理,您可以使用public、public_class_method将方法设为public类型。
在默认情况下,类中的方法都被定义成public类型(initialize除外),而顶层中的方法会被定义成private类型。
5.8 方法名可以用大写字母开头吗?
可以。但要注意:即使方法调用中不带参数,也不能省略方法名后的空括号。
5.9 为什么使用super时会出现ArgumentError?
在方法定义中调用super时,会把所有参数都传给上层方法,若参数个数不符合其要求,就会引发ArgumentError。因此,若参数个数不合时,应该自己指定参数然后再调用super。
5.10 如何调用上2层的同名方法?
super只能调用上1层的同名方法。若想调用2层以上的同名方法时,需要事先对该上层方法进行alias操作。
5.11 重定义内部函数时,如何调用原来的函数?
可以在方法定义中使用super。进行重定义之前,使用alias就可以保住原来的定义。也可以把它当作Kernel的特殊方法来进行调用。
5.12 何谓破环性的方法?
就是能修改对象内容的方法,常见于字符串、数组或哈希表中。一般是这样的:存在两个同名的方法,一个会拷贝原对象并返回副本;一个会直接修改原对象的内容,并返回修改后的对象。通常后者的方法名后面带有!,它就是破坏性的方法。但是有些不带!的方法也是具有破环性的,如String#concat等等。
5.13 那些情况下会产生副作用?
若在方法中对实参对象使用了破环性的方法的时候,就会产生副作用。
def foo(str)
str.sub!(/foo/, "baz")
end
obj = "foo"
foo(obj)
print obj
#=> "baz"
此时,参数对象的内容被修改。另一方面,如果在程序中确有必要的话,也会对某对象发送具有副作用的消息,那就另当别论了。
5.14 能让方法返回多个值吗?
在Ruby中确实只能指定一个方法返回值,但若使用数组的话,就可以返回多个值了。
return 1, 2, 3
上例中,传给return的列表会被当作数组处理。这与下面的代码可谓是异曲同工。
return [1, 2, 3]
另外,若使用多重赋值的话,则可以达到返回多个值的效果。例如
def foo
return 20, 4, 17
end
a, b, c = foo
print "a:", a, "\n" #=> a:20
print "b:", b, "\n" #=> b:4
print "c:", c, "\n" #=> c:17
您也可以这样处理。
相关推荐
ruby的参考手册,中文的,谁想要直接下载的。不用积分呀。方便大家。
《Ruby完全自学手册》是一本完全覆盖Ruby和Ruby on Rails的完全自学手册。《Ruby完全自学手册》的特色是...《Ruby完全自学手册》适合准备学习或了解Ruby语言和IRails框架的各类读者阅读,并可作为开发人员的参考手册。
由于提供的【部分内容】中出现了大量的重复网址"***",这看起来像是一个错误或者广告性质的内容,并不是Ruby自学手册的有效信息。在查找学习资源时,建议访问专业的Ruby社区或者官方文档网站,比如Ruby官方网站、...
这份"Ruby中文参考手册"针对的是Ruby 1.8.1版本,虽然现在Ruby已经发展到更高级的版本,如3.x,但1.8.1仍然是许多开发者学习和工作中不可或缺的参考资料。这份手册包含了对Ruby语言的全面解释,包括函数、对象和接口...
2. **Ruby参考手册**: 这部分通常是对Ruby内置类库、方法、语法的详细参考,涵盖了标准库的所有模块和类,比如Array、Hash、String等。它提供了每个方法的用法、参数和返回值,是开发者在编写代码时查找特定功能或...
### Ruby袖珍参考手册知识点概览 #### 一、书籍简介 《Ruby袖珍参考手册》是一本旨在帮助Ruby开发者快速查找所需知识点的手册。无论你是通过Rails框架接触Ruby,还是因为Ruby是一种干净、强大且表达力丰富的语言而...
本参考手册是学习Rails 2.2.2的重要资源,特别适合初学者和有一定经验的开发者。它提供了详尽的API文档,帮助开发者深入理解Rails框架中的各个组件和方法。以下是一些关键的知识点: 1. **MVC架构**:Rails的核心...
这份电子版手册详细介绍了Ruby的核心概念、语法以及常见问题的解决方案,旨在帮助开发者快速掌握并熟练运用Ruby。 在Ruby的世界里,了解基本语法是入门的第一步。这包括变量(局部变量、实例变量、类变量和全局变量...
ruby完全自学手册电子书 part1 请与part2 一起下载。合并解压缩
- **官方文档**:Ruby和Rails都有非常完善的官方文档,是学习过程中不可或缺的参考资料。 - **在线教程**:互联网上有大量的免费和付费在线教程,这些教程通常会按照学习路径组织起来,适合初学者系统学习。 - **...
《Ruby完全自学手册》特色:涵盖基础知识、核心技术、典型示例等内容,按照“基本概念-核心语法-典型示例”的模式讲解,容易上手,提供180余个典型案例、4个项目案例。 超值光盘内容:《Ruby完全自学手册》源代码+...
Ruby完全自学手册].邓蔚.扫描版 Ruby完全自学手册].邓蔚.扫描版
这份"Ruby学习资料(含参考手册和Programming Ruby)-中文.rar"压缩包包含了一系列的资源,帮助初学者和进阶者深入理解Ruby语言。 首先,"ruby中文文档(含参考手册和Programming Ruby).chm"是一个综合性的中文参考...
《Ruby完全自学手册》是一本完全覆盖Ruby和Ruby on Rails的完全自学手册。《Ruby完全自学手册》的特色是...《Ruby完全自学手册》适合准备学习或了解Ruby语言和IRails框架的各类读者阅读,并可作为开发人员的参考手册。
ruby自学手册电子书patr2
《Ruby完全自学手册》是一本完全覆盖Ruby和Ruby on Rails的完全自学手册。《Ruby完全自学手册》的特色是...《Ruby完全自学手册》适合准备学习或了解Ruby语言和IRails框架的各类读者阅读,并可作为开发人员的参考手册。
【标题】:“doctree:日语Ruby参考手册存储库” 这个标题表明,这是一个与Ruby编程语言相关的资源库,特别是针对日语用户的。"doctree"可能是指文档树结构,意味着它是一个组织和管理Ruby文档的框架或系统,特别为...
总而言之,《Ruby完全自学手册》是一本全面覆盖Ruby语言各个方面的教程,无论是对编程初学者还是希望深入研究Ruby的开发者来说,都是一本不可多得的参考书。通过邓蔚的引导,读者可以系统地学习Ruby,掌握其精髓,...
本资源“Ruby完全自学手册光盘里的源代码”是针对初学者和进阶者设计的一份宝贵资料,旨在帮助读者通过实际操作来深入理解Ruby编程。 首先,源代码是编程学习的核心部分,它能让读者看到程序的实际结构和工作方式。...
myrurema是一种工具,可以轻松参考“ Ruby参考手册更新计划”(通常称为Rima)的参考,该参考书是下一代Ruby日语版。 安装 需要Ruby> = 1.8.x和Git。 使用RubyGems安装。 $ sudo gem install myrurema 然后,您...