Skip to content

Instantly share code, notes, and snippets.

@k33g
Created August 25, 2015 15:32
Show Gist options
  • Save k33g/9fdf20797fbd7bcbba6f to your computer and use it in GitHub Desktop.
Save k33g/9fdf20797fbd7bcbba6f to your computer and use it in GitHub Desktop.
module frankenstein
import javassist.ClassPool
import javassist.CtField
import javassist.CtNewMethod
import gololang.Adapters
struct dynamicClass = {
className,
fields,
methods,
_ctClass
}
augment dynamicClass {
function field = |this, fieldName, fieldType| {
this: fields(): put(fieldName, fieldType)
return this
}
function method = |this, methodName, closure| {
this: methods(): put(methodName, closure)
return this
}
function toClass = |this| {
let resolveCtClass = |clazz| {
let pool = ClassPool.getDefault()
return pool: get(clazz: getName())
}
this: fields(): each(|fieldName, fieldType| {
let field = CtField(resolveCtClass(clazz= fieldType), fieldName, this: _ctClass())
field: setModifiers(javassist.Modifier.PUBLIC())
this: _ctClass(): addField(field)
})
this: methods(): each(|methodName, closure| {
let method = javassist.CtNewMethod.make(
"public Object "+ methodName +"() { return null ; }"
, this: _ctClass()
)
this: _ctClass(): addMethod(method)
})
let klass = this: _ctClass(): toClass()
let klassDef = Adapter(): extends(this: className())
this: methods(): each(|methodName, closure| {
klassDef: implements(methodName, |this| {
return closure(this)
})
})
return klassDef
}
}
function DynamicClass = |className| {
let pool = ClassPool.getDefault()
let ctClass = pool: makeClass(className)
let dynaKlass = dynamicClass(className, map[], map[], ctClass)
return dynaKlass
}
function main = |args| {
let Human = DynamicClass("org.k33g.Human")
: field("name", String.class)
: field("age", Integer.class)
: method("hello", |self| {
println("Hello " + self: name())
})
: method("yo", |self| {
println("yo " + self: name() + ", your age: " + self: age())
})
: toClass()
let bob = Human: newInstance()
bob: name("Bob Morane"): age(42)
bob: hello()
bob: yo()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment