以下内容纯粹为本人以前学习 Ruby 时的笔记整理。限于个人理解能力,可以肯定一定有 大量的错误,与其说分享,不如说是写出来让大家检查。如果有什么不对,或不准确的 地方,也希望前辈们一定多多指正,不吝赐教。
我希望这里是一个具有良好氛围的中文社区 (我梦寐以求的那个 Ruby 中文社区) 所以我不 希望出现针对这个帖子的不和谐言语或对针对本人的任何不良言语.
总共分为五大部分:每一部分都有上百条,可能会有重复,有些就是直接抄书。都是我 个人的理解以及对某些文章片段的延伸,大家就将就着看了。
markdown 格式折腾了一下午,托万能 Emacs 的福,使用 markdown-mode 搞定了。现在才觉 出 edit-server 的好来,这是另一个 Emacs 插件,可以让我在 Emacs 下使用特定的模式直 接编辑 Chrome 浏览器打开的表单,不过也许用惯了 org-mode 的缘故,这个 markdown 依旧 觉得很不习惯。
顺便提个建议:我总觉得应该开个 lisp 版块。我想凡是接触过 lisp(或 elisp) 的人,应该 都会觉得这两门语言惊人的相似,混入,布尔真假等等,如果说 Ruby 字符串 (尤其是 1.9) 及其强大,完全继承自 Perl 的话,我倒是觉得骨子里的东西 (类,模块) 甚至面向对 象的方式 (Ruby 一切都是对象,lisp 一切都是列表) 都和 lisp 惊人的相似,即使表面上 看起来这是完全不同的两种语言,甚至是不同类型语言。
Ruby 新人可以看看我的基础理论部分,这也是当初我学习 Ruby 心路历程,虽然有些问题很初级,但是我就是这样一步一步走过来的。
类相关部分全是都是关于 Ruby 的基石类的概念。这部分的概念极多.超级复杂,也很抽象,如果你真正理解了 Ruby 的对象模型,会有及其惊艳的感觉。这部分的东西,这部分的大部分内容都是双眼瞪着天花板冥思苦想,也偶尔查阅源码而写出的。深有感触,有什么不对的地方,欢迎高手指正。
小提示部分也很杂乱,这是感觉自己脱离了基础部分之后,写的一些小技巧。
常犯错误部分不用说了,直到现在自己仍旧屡犯不止的错误。
ruby 惯例是自己整理的一些`非必须'的小技巧,但是作为 Ruby 惯例,应该支持。
下面的内容,都是含有鲜明的`Ruby 特色'的基础理论。
Ruby内一切都是对象, 没有基本类型和对象类型的区别.
例如:
1.class # => Fixnum, 调用 1 的方法,显示 1 这个 (数字) 对象所属的类.
0.0.class # => Float, 显示 (浮点数) 对象所属的类。
关注类型而不是类, 形成了Ruby当中一种被称为`duck typing'的编程风格.
ducktyping 是 ruby 的世界里的基本价值观之一.
在这种机制下,对象的有效语义是由它所拥有的方法和属性集来决定的,而不是由他所继承的类来决定的。我们常常不太在意一个对象所属的类是什么,只想知道这个对象是否可以调用某些方法。
如果一个方法定义在类或者模块之外, 那么他就是一个全局函数, 而不是一个方法.
(但是从技术角度来讲,所有的类继承自 Object. 所以,这个方法会成为 Object 类的私有方法) 在 Kernel 模块当中定义的方法是全局函数,就好比在所有类之外的顶层空间中定义的方法。
Ruby对象将它所有的内部实例变量封装起来, 只对外保留一些方法.
`注意:有些方法没有实参,调用它时省略了圆括号,所以看起来就像个变量引用。我们称这样的方法叫做属性访问器方法.(properties)
在类定义之外, 实例变量是不可见的(面向对象的封装), 常见的`变量'其实是"属性方法".
方法永远是在一个对象上被调用的! self这个关键字总是代表调用方法的那个对象.如果调用方法时不指定对象, 该方法被隐式的在self上被调用.
如果一个对象定义了一个以=结尾的方法, 并且该方法接受一个实参, 这个方法叫做属性可变方法Ruby会在处理一个赋值操作的时候调用它.
例如:
myobject.x=(1) 等价于 myobject.x = 1
像m=这样的方法通常都会有一个对应的m方法, 它返回最近一次传递给m=的值. 这一对方法就是属性的原型.
任何对象都可以定义一个[]方法, 当使用方括号来索引该对象时, 任何位于方括号当中的值都会被作为实参传递给[]方法.
例如:
a[0] 等价于 a. # => 方法名为 []
o[x]=y 等价于 o.[]=(x,y) # => 方法名为 []= x+y 等价于 x.+(y) # => 方法名为+
Ruby当中语法糖的通用法则是:"去点去括号".
例如:x. <==> x[0] x.==(y)
<==> x == y x.+(y) <==> x + y
Ruby当中的`+操作符'是不会自动针对`右侧操作数'执行类型转换的.(即,不会自动调用右侧的`to_类型'方法)
换个说法,Ruby当中的+方法是个特例,它没有实现针对duck typing的多态性.
'文本'* N 返回一个重复文本N次的字符串.如果文本内有`字符串插值'操作,该操作只会在重复操作之前被执行一次.
[1,2,3] * ":" # => "1:2:3"
ruby可以使用循环,但是循环一般都是和一些方法的调用语句搭配使用.使用代码块迭代更有效.
常量拥有全局可见性, 并且应当最多只被赋值一次. 可以在Ruby程序的任何地方使用它们而不考虑作用域.
常量绝对不会处于未初始化状态.与变量不同,只有在真正执行了对常量的赋值表达式以后,常量才会存在.只有将nil赋值给一个常量时, 该常量才会有nil值.
以大写字母开头的字符,通常表示常量. 常量拥有全局可见性, 应该只会被求值一次.在Ruby中, 在修改一个常量时, 解释器会返回一个警告而不是错误.为了避免混乱,你不应该去改变常量的值.
Ruby当中,常量并不代表一个特定的类型(Type). 只不过是一个大写字母开头的变量而已.
Ruby当中真正的常量其实只有整数和符号两种而已.
Ruby当中,表达式和语句之间没有清晰的界限,Ruby当中的所有东西,包括类和方法的定义在内,都可以作为一个表达式来求值,并且返回一个该表达式最后一条语句的值.方法定义是一个例外, 他总是返回nil.