Reputation: 31
I'm having trouble with Smalltalk. Is there some operator like "is in" or "is contained / included"?
I have classes Student and Exam (with attribute student) and collections StudentsList and ExamsList. In the ExamsList, I would like to show all instances of class Exam that meet the criteria that their student (object set as value of attribute student) is contained in collection StudentsList.
Something like the following code, but it does not work:
ExamsList list: (Exam allInstances select: [ :ex | (StudentsList includes: ex student) ]).
Could you think of some elegant solution?
Many thanks!
Upvotes: 2
Views: 364
Reputation: 14843
Even though your question lacks some information, there are a few comments that might help.
If your naming convention is consistent and ExamsList
is a class, then StudentsList
must be a class too. In that case your code doesn't work because classes do not understand the message #includes:
, which is intended to be sent to subinstances of Collection
.
Assuming my guess is applicable, I would point out that it is not a good idea to have a class for every collection of objects. So, instead of having the class ExamsList
, you should add a class variable Exams
to the class Exam
, initialized to a Set
and store there every instance of Exam
that you want to preserve for future queries.
In the same way, you should add a class variable Students
to the class Student
and get rid of StudentsList
.
With this design every new instance that matters should be saved in the corresponding collection held by the class (see 6 below for a hint on how to do this). This would eliminate the need for enumerating #allInstances
.
In any case, you should understand that #allInstances
is a system message, i.e., it is not intended for querying objects in the realm of your model as it belongs in much lower level of abstraction. Note that #allInstances
will collect instances that for whatever reason (tests, examples, open debuggers or inspectors, etc.) may still be around without being part of your model.
If every Exam
has a Student
, you could store an Exam
in the Exams
collection whenever you assign it to the designated Student
, something on the lines of
Exam >> forStudent: aStudent
Exams add: self.
student := aStudent
(student
is an ivar of Exam
, and self
represents the instance with concrete questions)
Upvotes: 3