- Array可以用literal和new的方式创建:
anArray = [] # 用literal的方式
anArray2 = Array.new # 使用new的方式
- Array可以用[]来索引,内容是动态的增长的。如果[]里面是负数的话,那么就是从尾部开始索引。实际上[]是一个函数调用。
- [n1, n2]表示从n1开始的n2个元素。[n1..n2](注意中间是2个点)表示区间[n1, n2],而[n1...n2](中间3个点)表示区间[n1, n2)。
- []=这个函数(或者说操作符)可以给Array赋值。根据下标选择的范围不同,会将该范围内的元素替换成=号右边的元素,长度会自动调整。如果选择的范围长度是0,那么在该元素之前插入元素。
a = [ 1, 3, 5, 7, 9 ] » [1, 3, 5, 7, 9]
a[1] = 'bat' » [1, "bat", 5, 7, 9]
a[-3] = 'cat' » [1, "bat", "cat", 7, 9]
a[3] = [ 9, 8 ] » [1, "bat", "cat", [9, 8], 9]
a[6] = 99 » [1, "bat", "cat", [9, 8], 9, nil, 99] # 中间缺掉的元素自动用nil补上
class SongList
def [](key)
if key.kind_of?(Integer) # 这里的kind_of?函数是obj的一个函数,当obj是class的对象或者其子类的对象时返回真。
@songs[key]
else
# ...
end
end
end
- 使用if modifier和code block可以简化很多代码,同时code block和iterator配合起来使用会非常方便。
class SongList
def [](key)
return @songs[key] if key.kind_of?(Integer)
return @songs.find { |aSong| aSong.name == key }
end
end
- iterator(迭代器)实际上是一个方法,他会利用code block来对container里面的元素进行迭代的操作,这一点和Lisp是相同的。在方法里面,调用code block要用yield方法,而yeild方法是可以改变当前上下文(context)中的变量的值,并且也可以返回值的。
class Array
def inject(n)
each { |value| n = yield(n, value) }
n
end
def sum
inject(0) { |n, value| n + value }
end
def product
inject(1) { |n, value| n * value }
end
end
[ 1, 2, 3, 4, 5 ].sum » 15
[ 1, 2, 3, 4, 5 ].product » 120
- 可以用code block来实现一个自动transaction的概念,也就是在执行完code block的代码之后,执行一些必须的结束前的操作。
class File
def File.myOpen(*args) # 这里的*args的意思是将所有的参数都放在一个Array里面,然后传递给args。
aFile = File.new(*args) # 这里的意思是将args的内容又重新变回原来的那种参数样子。
# If there's a block, pass in the file and close
# the file when it returns
if block_given? # 这个方法是检查本方法是否被传递了一个code block。
yield aFile
aFile.close
aFile = nil
end
return aFile
end
end
- 一个code block可以被转化成一个Proc对象,这个对象有一个call方法用来调用这个code block。
class JukeboxButton < Button
def initialize(label, &action) # &action的意思是将这个方法给予的code block转化成Proc对象,并传递给action。这个只能出现在最后一个参数上。
super(label)
@action = action
end
def buttonPressed
@action.call(self)
end
end