你可以自己实现它。
看一下草案解决方案:
class Campus
attr_reader :students
def initialize
@students = []
end
def [](ind)
students.detect{|s| s.id == ind}
end
def <<(st)
raise "Yarrr, not a student" if st.class != Student
raise "We already have got one with id #{st.id}" if self[st.id]
students << st
end
end
class Student
attr_accessor :id, :name, :prop
def initialize(id, name, prop)
@id, @name, @prop = id, name, prop
end
end
campus = Campus.new
st1 = Student.new(1, "Pedro", "Math")
st2 = Student.new(2, "Maria", "Opera")
campus << st1
campus << st2
campus[1]
campus[2].name
campus[2].id = 10
campus[2]
campus[10].name
或者您可以尝试使用数组类(如果您确实需要,也可以使用哈希表):
class StrangeArray < Array
def [](ind)
self.detect{|v| v.id == ind} || raise "nothing found"
end
def <<(st)
raise "Looks like a duplicate" if self[st.id]
self.push(st)
end
end
campus = StrangeArray.new
campus << Student.new(15, 'Michael', 'Music')
campus << Student.new(40, 'Lisa', 'Medicine')
campus[1]
campus[15].prop
campus[15].id = 20
campus[20].prop
在@tadman提出正确评论之后,您可以直接在学生类中引用您的hash
:
class Student
attr_accessor :name, :prop
attr_reader :id, :campus
def initialize(id, name, prop, camp=nil)
@id, @name, @prop = id, name, prop
self.campus = camp if camp
end
def id=(new_id)
if campus
rase "this id is already taken in campus" if campus[new_id]
campus.delete id
campus[new_id] = self
end
@id = new_id
end
def campus=(camp)
rase "this id is already taken in campus" if camp[id]
@campus = camp
camp[@id] = self
end
end
campus = {}
st1 = Student.new(1, "John", "Math")
st2 = Student.new(2, "Lisa", "Math", campus)
st1.campus = campus
campus[1].name
campus[1].id = 10
campus[10].name
detect
循环遍历所有值是否是解决这个问题的特别明智的方法。 - tadmanid
是一个不可变的数据库属性。我已经添加了一个针对该解决方案进行优化的答案。 - tadman{|s| s.id == ind}
,因此我可以将其用于非学生(我将接受您的答案,所以如果您愿意,可以更新以备后人)。我只是想看看是否有更好的方法,没有抱太高的希望。 - alexloh