Peanut's Book Shelf » 日志 » Why Ruby amazes me? PRuby Chap 4:容器,Blocks和迭代器
Why Ruby amazes me? PRuby Chap 4:容器,Blocks和迭代器
Gem Gatherer 发表于 2007-10-28 21:37:33
a[3.14159,"pie",49]
a.class -> Array
a.length -> 3
a[3] ->nil
[]实际上是一个方法。
如果用负数作为索引,那么会从数组末端开始计数
数组可以嵌套 // cool.
数组可以自嵌套
a= [1]
a[0]=a
居然不出错。。。omg。。。
可以用a[start,count] 来取数组的子集
a=[1,3,5,7,9]
a[1,3] -> [3,5,7]
a[3,1] ->[7]
a[-3,2] -> [5,7]
也可以用range来对数组进行索引
a[1..3] =[3,5,7]
a[1...3]=[3,5]
a[3..3]=[7]
a[-3...1]=[5.7.9]
也可以用[start,count]或者是range对某个范围进行追加,插入和替换(替换的数组长度不同也完全没关系...)
h= { 'dog' => 'canine', 'cow' => 'bovine', 'cat'=>'feline' }
直接用下标可以访问和插入
Array类简单介绍
push : 尾部压入
pop: 删除尾部元素
shift: 删除首部元素
实现重载操作符[]
def [](index)
@songs[index]
end
重头戏:Block
一般构想的查找方式
def with_title(title)
for i in 0...@song.length
return @songs[i] if title == @songs[i].name
end
return nil
end
有着更加自然的方式
def with_title(title)
@songs.find{ |song| title == song.name }
end
这里的find就是一种迭代器。它反复调用block里面的代码
** block里的代码可以被带着它的函数用yield调用。
yield可以带任意个参数
#Tip:多重赋值
i1,i2=i2,i1+i2 //Easy Fibonacci!!:)
#Tip : 检测变量是否已经定义过
defined?(c) ->nil
#Tip : 新的迭代器: each, collect
[1,3,5,7,9].each { |i| puts i } // 简单,但是不能指望它给你返回什么新的集合。
{"H" ,"A", "L"}.collect {|i| i.succ} -> {"I", "B", "M"}
另一个例子
f = File.open("FileName")
f.each do | line |
puts line
end
f.close
#Tip : 新的迭代器 : inject
让你可以利用数组中所有的元素生成一个值。
[1,3,5,7].inject(0) { | sum,element | sum+element} #第一个0是初值
#Tip:不关心具体参数内容的参数传递
def File.Open_the_process(*args)
f=File.open(*args) #超超超酷
yield
f.close
end
思想:文件应由打开者自行负责关闭。因此文件的关闭打开就和yield的process逻辑分开了
File直接支持自行管理生命周期
如果open有个block,那么该block将被调用,且参数是文件。执行结束文件会关闭
如果open没有block,那么单纯返回打开的文件对象
#Tip : 判断函数是否带有block
if block_given?
yield file
file.close
end
def initialize(label, &action )
super(label)
@action=action #调用该方法时,ruby会寻找一个block,将其转化为一个proc对象并赋值给参数
end
def button_pressed
@action.call(self)
end
#Tip Lambda
def n_times(thing)
return lambda { |n| thing*n}
end
