ExpandoObject implementation in Scala

I am trying to implement a C # ExpandoObject in Scala. Here's how it should work:

 val e = new ExpandoObject e.name := "Rahul" // This inserts a new field `name` in the object. println(e.name) // Accessing its value. 

Here is what I have tried so far:

 implicit def enrichAny[A](underlying: A) = new EnrichedAny(underlying) class EnrichedAny[A](underlying: A) { // ... def dyn = new Dyn(underlying.asInstanceOf[AnyRef]) } class Dyn(x: AnyRef) extends Dynamic { def applyDynamic(message: String)(args: Any*) = { new Dyn(x.getClass.getMethod(message, args.map(_.asInstanceOf[AnyRef].getClass) : _*). invoke(x, args.map(_.asInstanceOf[AnyRef]) : _*)) } def typed[A] = x.asInstanceOf[A] override def toString = "Dynamic(" + x + ")" } class ExpandoObject extends Dynamic { private val fields = mutable.Map.empty[String, Dyn] def applyDynamic(message: String)(args: Any*): Dynamic = { fields get message match { case Some(v) => v case None => new Assigner(fields, message).dyn } } } class Assigner(fields: mutable.Map[String, Dyn], message: String) { def :=(value: Any): Unit = { fields += (message -> value.dyn) } } 

When I try to compile this code, I get a StackOverflowError . Please help me get this job. :) Thank you.

+7
source share
1 answer

Got a job after some games. The solution is not typical, although (which in this case does not matter, since the point of this small utility is to work on the type system. :-)

 trait ExpandoObject extends Dynamic with mutable.Map[String, Any] { lazy val fields = mutable.Map.empty[String, Any] def -=(k: String): this.type = { fields -= k; this } def +=(f: (String, Any)): this.type = { fields += f; this } def iterator = fields.iterator def get(k: String): Option[Any] = fields get k def applyDynamic(message: String)(args: Any*): Any = { this.getOrElse(message, new Assigner(this, message)) } } implicit def anyToassigner(a: Any): Assigner = a match { case x: Assigner => x case _ => sys.error("Not an assigner.") } class Assigner(ob: ExpandoObject, message: String) { def :=(value: Any): Unit = ob += (message -> value) } 
+4
source

All Articles