1. [1, "string", 2, ["nested", "array"]]
数组元素可以使用任意对象
arr=[1,2,"str",[1,2,4]]
p arr[3] #输出[1,2,4]
p arr[-1] #输出[1,2,4]
arr.each { |item|
p item
}
#输出1 2 "str" [1,2,4]
2. 在Ruby中,无论是变量还是常量,全都保持着引用(reference)。因此,将一个变量赋值给另一个变量时,不会发生复制。
Ruby变量的首字符表示变量的类型(作用域)。
以小写字母或下划线开头的表示局部变量。
变量名以大写字母开头的是常量
根据Ruby的变量命名规则,第一个字母决定类型。实例变量是“@”。
变量名以@@开头的就是类变量。
在程序的任何位置都可以对全局变量进行赋值和访问。变量名的第一个字符为$的就是全局变量
最初的赋值兼做变量声明,无需额外声明。变量是无类型的,因此,无论何种类型,都可以无差别的赋值
Str="HelloWorld"
Str="Yes" # Str是常量,Ruby将抛出警告: warning: already initialized constant Str
3.对于条件表达式,只有两个对象——false和nil——为假,其余所有对象都是真。0和空字符串也是真
if i <10 then
p i
end
while i<10 do
p i
end
4. Ruby的类名与常量名是等价的。那么,与类名同名的常量是什么呢?实际上,就是这个类。在Ruby中,所有能操作的东西都是对象。
类自然也是对象。这种对象称为类对象。所有的类对象都是Class类的实例。 也就是说,创建新类对象的class语句,
其动作是将类对象赋值给一个与类同名的常量。另一方面,生成实例的操作是,访问这个常量,通过该对象调用方法(通常是new)
在方法执行过程中,通常会保留自己(方法调用的实例)是谁的信息,这个信息可以通过self得到。类似于C++或Java中的this。
使用this,Ruby将抛出异常
有时需要对一个类进行特定的初始化。这时要修改的不是new方法,而是一个名为initialize的方法。它会在new的过程中调用。
5. 只能指定一个超类。看起来Ruby似乎是单一继承。但是,因为模块的存在让它拥有了与多重继承同等的能力。下面就来讨论一下模块。
一言以蔽之,模块就是“无法指定超类,无法生成实例”的类。定义可以这样写。
然而它无法直接调用,因此不能创建实例。那么该怎么用呢?应该由其它类“include”这个模块。这样一来,就好像类继承自这个模块一样
module M
def myupcase( str )
return str.upcase()
end
end
class C
include M
end
p(C.new().myupcase("content")) # 显示"CONTENT"
M的定义必须在C的定义前面,否则将抛出异常
class Cls
def test()
return "class"
end
end
module Mod
def test()
return "module"
end
end
class C < Cls
include Mod
end
p(C.new().test()) # “class”? “module”?
模块和类哪边更“近
6. 开头加上::,表示“这是一个定义在顶层的常量”。就像文件系统的路径一样。假设根目录下有个叫vmunix的文件。
在/下只写vmunix就可以访问它。而在全路径下就要写/vmunix。Const和::Const也是同样的关系。在顶层下,可以只写Const,
也可以按照全路径写::Const。
class SomeClass
Const = 3
end
p(::SomeClass::Const) # 显示3
p( SomeClass::Const) # 同样显示3
class C1 # ::C1
ConstC1="ConstC1";
class C2 # ::C::C2
ConstC2="ConstC2";
class C3 # ::C::C2::C3
ConstC3="ConstC3";
end
end
end
p ::C1::C2::ConstC2 #显示 ConstC2
7. 顶层、类定义语句内、模块定义语句内、方法体内,都有各自完全独立的局部变量作用域。
Ruby程序执行过程中,到处都设置了self。就连顶层和类定义语句中都有self。
比如,顶层甚至也有self。顶层的self称为main。没什么奇怪的,它就是Object的实例。
main仅仅是为了设置self而准备的,没有什么更深层的含义。
因为顶层的self,也就是main,是Object的实例,所以,即便是在顶层也可以调用Object的方法。
而且Object包含了一个称为Kernel模块,其中定义了“函数风格的方法”,像p、puts。(图10)。
因此,即便在顶层也可以调用p和puts。
8. Ruby对于程序库的加载也全都是在执行时进行的。通常这样写。
Ruby代码
require("library_name")
同看到的一样,require是一个方法。根本没有保留字。这样写的话,就在其所写的地方执行加载,执行就转移到那个程序库(的代码)。
因为Ruby中没有Java中包的概念,如果希望划分程序库名称的名字空间,就将文件分开放置到目录里。
9. 使用模块作为名字空间
# net程序库的名字空间划分的例子
module Net
class SMTP
# ...
end
class POP
# ...
end
class HTTP
# ...
end
end
10. singleton方法(singleton method)
对象可以调用方法。可以调用的方法由对象的类决定。但是理想情况下,方法是属于对象的。
至于类,它的存在是为了省去多次同样方法的时间。
实际上,Ruby有一种机制,可以为对象(实例)单独定义方法,无论它们的类是什么。这样写。
Ruby代码
obj = Object.new()
def obj.my_first()
puts("My first singleton method")
end
obj.my_first() # 显示My first singleton method
众所周知,Object是所有类的超类。在这么重要的类中,不可能定义一个像my_first名称这样怪异的方法。
obj是Object的实例。但是,obj却可以调用my_first方法。
也就是说,肯定在哪定义了这个与所属类完全没有关系的方法。这样为某个对象定义的方法称为singleton方法(singleton method)。