Skip to content

Instantly share code, notes, and snippets.

@teigen
Created January 17, 2011 22:01
Show Gist options
  • Save teigen/783575 to your computer and use it in GitHub Desktop.
Save teigen/783575 to your computer and use it in GitHub Desktop.
Do we need Dynamic ?
/* lib */
trait Dynamic {
def _select_(name: String):Dynamic
def _invoke_(name: String)(args: Any*):Dynamic
def ~ (name: Symbol) = _select_(name.name)
def ~ (invocation:Invocation) = _invoke_(invocation.name)(invocation.args :_*)
def typed[T]:T = asInstanceOf[T]
}
class Invocation(val name:String, val args:Any*)
implicit def invokeSymbol(s:Symbol) = new {
def apply(args:Any*) = new Invocation(s.name, args :_*)
}
/* usage */
class DynamicImpl(x: AnyRef) extends Dynamic {
def _select_(name: String): DynamicImpl = {
new DynamicImpl(x.getClass.getMethod(name).invoke(x))
}
def _invoke_(name: String)(args: Any*) = {
new DynamicImpl(x.getClass.getMethod(name, args.map(_.asInstanceOf[AnyRef].getClass) : _*).invoke(x, args.map(_.asInstanceOf[AnyRef]) : _*))
}
override def typed[T] = x.asInstanceOf[T]
override def toString = "Dynamic(" + x.toString + ")"
}
implicit def toDynamic(x: Any): Dynamic = new DynamicImpl(x.asInstanceOf[AnyRef])
class Ruby {
def name = "Ruby"
def hello(name:String) = println("Hello " + name + " from ruby")
}
class Groovy {
def name = "Groovy"
def hello(name:String) = println("Hey " + name + " baby! - Are you feeling groovy")
}
def sayHi(dyn:Dynamic) = {
println((dyn ~ 'name).typed[String] + " says:")
dyn ~ 'hello("Dynamic")
}
sayHi(new Ruby)
sayHi(new Groovy)
/* output..
Ruby says:
Hello Dynamic from ruby
Groovy says:
Hey Dynamic baby! - Are you feeling groovy
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment