我正在通过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