我正在通過Bruce Tate的七週的七種語言,並試圖完成所有練習。有一個Tree練習,用戶只需將初始化程序更改爲接受散列並從中創建樹。我最初的嘗試如下:爲什麼這個ruby代碼不會拋出異常?
def initialize(hash={})
if !hash.keys[0].nil?
@node_name = hash.keys[0]
@children = []
if !(hash.values[0].nil? or hash.values[0] == {})
hash.values[0].each do |k, v|
@children.push(Tree.new({k => v})
end
end
end
end
This works。但是,沒有檢查的代碼也是可行的,例如:
def initialize(hash={})
@node_name = hash.keys[0]
@children = []
hash.values[0].each do |k, v|
@children.push(Tree.new({k => v})
end
end
爲什麼不需要檢查?看起來像我會得到像空引用的東西(我來自.Net背景,所以它可能被稱爲別的在紅寶石)。
這裏是我的全碼:
if !(hash.values[0].nil? or hash.values[0] == {})
hash.values[0].each do |v|
k = hash.key(v)
@children.push(Tree.new({k => v})
end
end
你可以在這種情況下得到異常:
hash = {}
hash.values # => []
hash.values[0] # => nil
class Tree
attr_accessor :children, :node_name
def initialize(hash={})
@node_name = hash.keys[0]
@children = []
hash.values[0].each do |k, v|
@children.push(Tree.new({k => v})
end
end
def visit_all(&block)
visit &block
children.each{|c| c.visit_all &block}
end
def visit(&block)
block.call self
end
end
ruby_tree = Tree.new({"grampa" => { "dad" => { "son1" => {}, "son2" => {}}, "uncle" => { "nephew1" => {}, "nephew2" => {"youngun1" => {}}}}})
puts "Visiting a node"
ruby_tree.visit {|node| puts node.node_name}
puts
puts "visiting entire tree"
ruby_tree.visit_all {|node| puts node.node_name}
一件小事:你可以寫'@children = hash.values [0] .map {| k,v | Tree.new(k => v)}'。當Ruby是一個參數時,Ruby允許你寫一個沒有大括號的散列。 –
爲了完整起見,Ruby中沒有空引用。永遠。任何引用將始終是有效的對象。 –
啊。那麼在最壞的情況下,這將是一個Nil對象的NoSuchMerhod? – tjcertified