我正在尝试复制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
您从未将@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
经过一个晚上的良好睡眠和更多的谷歌搜索,我找到了答案。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