If you hate the code containing the iterated objects' names twice, like:
object Content1 {...}
object Content2 {...}
object Content3 {...}
val iterated = Seq(Content1, Content2, Content3)
then the Macro features have to be used, and I'm not familiar with them :P
Also if you need the function to be somehow typed, then please wait for another answer because it should need TypeTag
s that I don't think I have enough knowledge about.
Otherwise, by that I mean if anything can be the iterated objects, then have all the parents inherit some Traversable
, and make a method like:
def iterateAnies(s: Any)(f: Any => Unit) {
f(s)
s match {
case s: Traversable[_] => s.foreach(iterateAnies(_)(f))
case _ =>
}
}
If objects need to be HAS-A, then make another trait having a Traversable[_]
and modify the iterateAnies
method so it takes in the trait as s
, have the f
takes in the trait too, and the match
part is gonna be upside-down:
trait HasTraversable {
def traversable: Traversable[_]
}
def iterateAnies(s: HasTraversable)(f: HasTraversable => Unit) {
f(s)
s.traversable.foreach(_ match {
case c: HasTraversable => iterateAnies(c)
case _ =>
})
}
With this you can print out their toString
doing like:
val something: Any = ... //or HasTraversable
iterateAnies(something)(println(_.toString))
iterateAnies(something)(println(_ match {
case s: String => "text"
case s: Int => "number"
case s: _ => "idk"
)})
To keep track of the depth, add an Int parameter to both iterateAnies
and f
and increment the value while the process.
If nobody answers and you need it typed like iterateAnies[A]
, then let me know and I will do my best, but I'm pretty sure somebody's gonna answer even with Macro features :)