我正在尝试复制Sinatra的功能。特别是类似DSL的部分,您可以在其中定义类的定义中的路由。当我尝试运行我的版本的人 - DSL时,我在第11行得到错误undefined method '<<' for nil:NilClass
。
class Persons
class << self
def reset!
@persons = []
end
def add_person title, name
@persons << {
title: title,
name: name
}
end
end
reset!
end
class MyPersons < Persons
add_person 'Dr.', 'Bob'
add_person 'Mr.', 'Jones'
end
答案 0 :(得分:1)
您永远不会将@persons
初始化为除nil以外的任何内容。一个简单的解决方法是
class MyPersons < Persons
reset!
add_person 'Dr.', 'Bob'
add_person 'Mr.', 'Jones'
end
您致电reset!
的原因不起作用的原因是MyPersons
和Persons
不共享相同的@persons
变量。
您可以使用@@persons
来共享变量。你的例子看起来像这样:
class Persons
@@persons = []
class << self
def reset!
@@persons = []
end
def add_person title, name
@@persons << { title: title, name: name }
end
end
end
class MyPersons < Persons
add_person 'Dr.', 'Bob'
add_person 'Mr.', 'Jones'
end
答案 1 :(得分:0)
经过一夜好眠和一些谷歌搜索后,我想出了答案。 Ruby中似乎有一个#inherited
方法;当一个类被继承(duh)时调用。
实际上,这就是Sinatra在Sinatra::Base
中实现实例变量的方式。
class Persons
class << self
def reset!
@persons = []
end
def add_person title, name
@persons << {
title: title,
name: name
}
end
def inherited child
child.reset!
end
end
end
class MyPersons < Persons
add_person 'Dr.', 'Bob'
add_person 'Mr.', 'Jones'
end