Skip to content

Instantly share code, notes, and snippets.

@mccv
Created December 22, 2010 07:19
Show Gist options
  • Select an option

  • Save mccv/751217 to your computer and use it in GitHub Desktop.

Select an option

Save mccv/751217 to your computer and use it in GitHub Desktop.
Hobo Ruby send equivalent. Really just syntactic sugar for standard reflection stuff
import java.lang.reflect.Method
class Sendable(a: AnyRef) {
val methods = a.getClass.getDeclaredMethods
def wrapByte(b: Byte) = new java.lang.Byte(b)
def wrapShort(s: Short) = new java.lang.Short(s)
def wrapInt(i: Int) = new java.lang.Integer(i)
def wrapLong(l: Long) = new java.lang.Long(l)
def wrapFloat(f: Float) = new java.lang.Float(f)
def wrapDouble(d: Double) = new java.lang.Double(d)
def wrapBoolean(b: Boolean) = new java.lang.Boolean(b)
def wrapChar(c: Char) = new java.lang.Character(c)
def send(methodName: String, args: Any*) = {
val candidates = methods.filter(_.getName == methodName)
val mappedClasses = args.map(mapClass).toArray
candidates.find(method => {
val paramTypes = method.getParameterTypes
typesMatch(mappedClasses, paramTypes)
}) match {
case Some(method) => {
method.setAccessible(true)
val mappedArgs: Array[AnyRef] = args.map(wrapAny).toArray
method.invoke(a, mappedArgs:_*)
}
case _ => throw new NoSuchMethodException(methodName)
}
}
def typesMatch(args: Array[Class[_]], paramTypes: Array[Class[_]]): Boolean = {
args.length == paramTypes.length &&
args.zip(paramTypes).forall {case (arg, paramType) => paramType.isAssignableFrom(arg)}
}
def mapClass(a: Any): Class[_] = {
a match {
case b: Byte => classOf[byte]
case s: Short => classOf[short]
case i: Int => classOf[int]
case l: Long => classOf[long]
case f: Float => classOf[float]
case d: Double => classOf[double]
case b: Boolean => classOf[boolean]
case c: Char => classOf[char]
case o: AnyRef => o.getClass
case _ => classOf[Object]
}
}
def wrapAny(a: Any): AnyRef = {
a match {
case b: Byte => wrapByte(b)
case s: Short => wrapShort(s)
case i: Int => wrapInt(i)
case l: Long => wrapLong(l)
case f: Float => wrapFloat(f)
case d: Double => wrapDouble(d)
case b: Boolean => wrapBoolean(b)
case c: Char => wrapChar(c)
case o: AnyRef => o
}
}
}
object ToSendable {
implicit def toSendable(a: AnyRef) = new Sendable(a)
}
// this is how you use it
// you should just be able to paste this whole blob into the REPL
import ToSendable._
val s = "foo"
s.send("indexOf", "o")
val sb = new java.lang.StringBuilder()
sb.append("foo")
s.send("contentEquals", sb)
val al = new java.util.ArrayList[String]()
al.add("foo")
al.send("get", 1)
@jmhodges

Copy link
Copy Markdown

FYI, you are the devil.

@olix0r

olix0r commented Sep 28, 2011

Copy link
Copy Markdown

the horrrra. the horrrrrrrrrrrra!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment