块
使用方法
最普通的
ary = ["a", "b", "c"]
ary.each{|obj| p obj}
带索引的
ary = ["a", "b", "c"]
ary.each_with_index do |obj, idx|
p [obj, idx]
end
hash
address = {name: "Aaron Ryuy", tel: "15007160010"}
address.each do |key, value|
p [key, value]
end
#=> [:name, "Aaron Ryuy"]
#=> [:tel, "15007160010"]
替代异常
File.open("sample.txt") do |file|
file.each_line do |line|
p line
end
end
#等价于
file = File.open("sample.txt")
begin
file.each_line do |line|
p line
end
ensure
file.close
end
排序
a<=>b的结果
条件 | 返回值 |
---|---|
a < b时 | -1 (比0小) |
a == b时 | 0 |
a > b时 | 1 (比0大) |
array = ["ruby", "Perl", "PHP", "Python"]
sorted = array.sort
#sorted = array.sort{ |a, b| a<=>b }
p sorted
#=> ["PHP", "Perl", "Python", "ruby"]
sorted = array.sort{ |a, b| a.length<=>b.length }
p sorted
#=> ["PHP", "ruby", "Perl", "Python"]
sorted = array.sort_by{ |item| item.length }
p sorted
#=> ["PHP", "ruby", "Perl", "Python"]
定义带块的方法
def hello
(1..5).each do |i|
if block_given?
p yield(i)
else
p i
end
end
end
hello
#=> 1 2 3 4 5
hello{|i| i*2}
#=> 2 4 6 8 10
控制块的执行
方法 | 意义 |
---|---|
break | 块中执行break,会立即返回,没有返回值。 |
break 0 | 返回 0 |
next | 中断当前处理,返回nil, 继续执行下面的处理 |
next 0 | 返回 0 |
redo | 不要用,容易死循环 |
封装为对象
hello = Proc.new do |name|
p "hello, #{name}."
end
hello.call "Aaron"
局部变量与块变量
块变量是只能在块内部使用的变量,不能覆盖外部的局部变量
x = 1
y = 2
ary = [1, 2, 3]
ary.each do |x|
#这里的x是块变量,是不会改变外部的x的
#y会变为3
y = x
end
p [y, x]
#=> [3, 1]
x = 1
ary = [1, 2, 3]
ary.each do |x|
y = x
end
p [y, x]
#=> 报错,因为外部没有y
x = y = z = 0
ary = [1, 2, 3]
# ; 后面的y为块局部变量,不会影响外部的变量y
ary.each do |x; y|
y = x
z = x
p [x, y, z]
end
p [x, y, z]
#=> [1, 1, 1]
#=> [2, 2, 2]
#=> [3, 3, 3]
#=> [0, 0, 3]
=begin
块内部,没有对x进行赋值,所以不会影响到外部的x
块内部,虽然对y进行了赋值,但是y是块局部变量,不影响外部的y
块内部,对z进行了赋值,所以是最后一次循环的结果3
=end
将块封装为对象
hello = Proc.new do |name|
p "Hello, #{name}."
end
hello.call("Aaron")
&block
就是个Proc对象
def call_each(ary)
ary.each do |item|
p item
end
end
call_each [1, 2, 3]
def call_each(ary, &block)
#这里的&block就是下面块里的代码,所以与上面等价
ary.each &block
end
call_each [1, 2, 3] do |item|
p item
end