做七週七語言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
訂正
題主給的程序有點小錯誤,訂正後如下,注意
visit &block
和print ' ' * n
兩行的順序:回答
將第15行依題主意思由
改為
後,程式輸出結果是一致的。
結論
問題不存在。
每行程式碼執行的時候都有一個上下文,在上下文中儲存著這行程式碼可以存取的一些變數。區塊可以存取定義時的上下文,在你的例子中這個區塊定義在全局,所以可以存取到全域變量,不過這裡的全域變數只有ruby_tree(也有一些語言內建的就不說了)。但是沒有block這個變量,所以在區塊內是不能存取的,會報類似不變量或方法存在的錯誤。
換一個解譯,如果用遠古的C語言類似的例子說的話,就是block這個變數是個實參,而你在區塊中要使用與其對待的形參node這個變數。