做七周七语言ruby第二天习题的时候要实现一个简单的Tree类,以下代码可以运行,但是把children.each {|c| c.visit_all(n+1) {|node| puts "-#{node.node_name}"}}
这行的{|node| puts "-#{node.node_name}"}改成&block
就跑不起来,请问是为什么?
#!/usr/bin/ruby
class Tree
attr_accessor :children,:node_name
def initialize(tree)
tree.each do |key,value|
@node_name = key
@children = value.map {|(key,value)| Tree.new(key => value)}
end
end
def visit_all(n,&block)
visit &block
print ' ' * n
children.each {|c| c.visit_all(n+1) {|node| puts "-#{node.node_name}"}}
end
def visit(&block)
block.call self
end
end
ruby_tree = Tree.new({
'grandpa' => {
'day' => {'child 1' => {},'child 2' => {}},'uncle' => {'child 3' => {},'child 4' => {}}
}
})
ruby_tree.visit_all(1) {|node| puts "-#{node.node_name}"}
ps: ruby环境是2.1.3
Correction
The program given by the questioner has a slight error. The corrected version is as follows. Pay attention to the order of the two lines:
Answervisit &block
和print ' ' * n
Each line of code has a context when it is executed, and some variables that can be accessed by this line of code are stored in the context. Blocks can access the context when they are defined. In your example, this block is defined globally, so you can access global variables. However, the only global variables here are ruby_tree (there are also built-in ones in some languages, which I won’t mention). However, there is no block variable, so it cannot be accessed within the block, and errors similar to the existence of invariants or methods will be reported.
Another interpretation, if we use a similar example from the ancient C language, the variable block is an actual parameter, and you have to use the formal parameter node variable to treat it in the block.