code block

  • code block ⼀种匿名⽅法
1
2
3
4
5
6
{ puts "Hello" } # 这是一個 block
do
puts "Blah" # 这也是一個 block
puts "B
end
  • 內部迭代器(iterator)
1
2
3
4
5
6
7
8
9
# 处理数组 people
people = ["David", "John", "Mary"]
people.each do |person|
puts person
end
# 反复五次
5.times { puts "Ruby rocks!" }
# 从一数到九
1.upto(9) { |x| puts x }
  • 其他迭代⽅式
1
2
3
4
5
6
7
8
9
# 迭代并造出另一个数组
a = [ "a", "b", "c", "d" ]
b = a.map {|x| x + "!" }
puts b.inspect
# 结果是 ["a!", "b!", "c!", "d!"]
# 找出符合条件的值
b = [1,2,3].find_all{ |x| x % 2 == 0 }
b.inspect
# 结果是 [2]
  • 当作判断条件
1
2
3
4
5
6
7
# 迭代并根据条件刪除
a = [ "a", "b", "c" ]
a.delete_if {|x| x >= "b" }
# 结果是 ["a"]
# 条件排序
[2,1,3].sort! { |a, b| b <=> a }
# 结果是 [3, 2, 1]
  • functional programming
1
2
3
4
5
6
7
# 计算总和
(5..10).reduce {|sum, n| sum + n }
# 找出最长字串find the longest word
longest = ["cat", "sheep", "bear"].reduce do |memo,
word|
( memo.length > word.length )? memo : word
end
  • 仅执⾏⼀次呼叫 pre- post- processing
1
2
3
4
5
6
7
8
file = File.new("testfile", "r")
# ...处理文件
file.close
# 但 Ruby 习惯⽤以下写法
File.open("testfile", "r") do |file|
# ...处理文件
end
# 文件自动关闭
  • Yield 在方法中使用 yield 可以执行 Code block 参数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 定义方法
def call_block
puts "Start"
yield
yield
puts "End"
end
call_block { puts "Blocks are cool!" }
# 输出
# "Start"
# "Blocks are cool!"
# "Blocks are cool!"
# "End"
带有参数的Code block
def call_block
yield(1)
yield(2)
yield(3)
end
call_block { |i|
puts "#{i}: Blocks are cool!"
}
# 輸出
# "1: Blocks are cool!"
# "2: Blocks are cool!"
# "3: Blocks are cool!"
  • Proc object 可以将Code block明确转成一个变数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
def call_block(&block)
block.call(1)
block.call(2)
block.call(3)
end
call_block { |i| puts "#{i}: Blocks are cool!" }
# 輸出
# "1: Blocks are cool!"
# "2: Blocks are cool!"
# "3: Blocks are cool!"
# 或是先宣告出 proc object (有三種寫法,大同小異)
proc_1 = Proc.new { |i| puts "#{i}: Blocks are cool!" }
proc_2 = lambda { |i| puts "#{i}: Blocks are cool!" }
proc_3 = -> (i) { puts "#{i}: Blocks are cool!" }
call_block(&proc_1)
call_block(&proc_2)
call_block(&proc_3)
# 分別輸出
# "1: Blocks are cool!"
# "2: Blocks are cool!"
# "3: Blocks are cool!"