What is the purpose of runtime mixins in groovy?
Mixins overall one of the ways to add functionallity to class without multiple inheritance issues. But what is its purpose in Groovy? Traits can do the same.
Annotation #Mixin is considered deprecated at all. Will runtime mixins have the same fate one day?
Runtime mixins give us the ability to add methods to existed classes at runtime. The important part of the answer is "existed" and "runtime".
So, you can easily add new methods to any 3rd party library at runtime.
Actually, recently I found a case where using mixins helped me a lot.
String.metaClass {
invokeMethod {
String name, args ->
System.out.println "[$name] invokation with $args"
}
}
class GroovyInterceptableWrapper
implements GroovyInterceptable {
}
String.mixin(GroovyInterceptableWrapper)
Though again if I used there trait instead of class and then invoked withTraits I would have achieved the same result.
Related
With current spec (2.0) there is no way to prevent class explosion
problem like what we do with decorator pattern:
Cake cakeWithToppings = new ColoredSprinklesDecorator(new ShavedChocolateDecorator(new ToastedCoconutDecorator(new BaseCake())));
cakeWithToppings.delish();
Now to do that with CDI our options are create all possible combinations
of cake toppings(2^3 = 8) as class or with producer method with qualifiers which
will create problem of qualifier and producer method explosion.
When GoF decorator used there is need for only 5 classes Cake, CakeDecorator, ColoredSprinklesDecorator, ShavedChocolateDecorator, ToastedCoconutDecorator, BaseCake.
And #Decorator doesn't solve this issue as i can see.
Is there any way I couldn’t think of or is cake lie?
I am not sure I fully grasp your point, but I'll give it a go...
I think you are mixing two things here - GoF's decorator pattern and CDI's decorator which is not quite an implementation of that pattern.
In CDI, #Decorator can be seen as a "semantics-aware" interceptor rather than implementation of GoF's Decorator pattern.
This means that it can wrap calls to underlying beans of given types while being able to leverage the semantics.
E.g. you can create a decorator which will wrap all calls to any Cake:
#Decorator
#Priority(1)
public class CakeDecorator implements Cake {
#Inject
#Delegate
Cake cake; // this will cause to it decorate all cakes
public void delish() {
// do stuff BEFORE actual cake's delish() invocation
addMoreChocolate(cake);
cake.delish(); // this is the original method invocation
// do stuff AFTER actual cake's delish() invocation
cleanUp(cake);
}
}
But you can also easily modify the decorator to trigger for only certain types of cakes - you can do that by either changing the delegate injection point, or simply by checking cake type withing the method body. You can also chain several decorators if you so wish.
I'd say CDI's decorator is meant to meet slightly different goals. You could in fact design a decorator accordingly to GoF's principles and then apply CDI's decorator on top of that.
I'd like to know if there is any way to add methods to library classes using Groovy traits.
From what I read here #Mixin is used for this, or you can use the runtime mixin approach with metaclass. Since #Mixin is now deprecated in favor of traits, any chance to achieve the same behavior by using traits or is runtime mixin the only option?
Thank you
Groovy also supports implementing traits dynamically at runtime. It
allows you to "decorate" an existing object using a trait.
You can decorate an object, however, I am afraid that it is not possible to decorate a class so that all its instances have the method available. See below a simple example that may help you or find more details here.
trait Extra {
String extra() { "I'm an extra method" }
}
class Something {
String doSomething() { 'Something' }
}
def s = new Something() as Extra
assert s.extra() == "I'm an extra method"
assert s.doSomething() == 'Something'
I have an annotation which adds some methods and default constructor to annotated class.
I have managed to create a gdsl, to enable autocompletion in idea for methods, but I'm stuck with constructor and documentation is very poor.
Does anyone have any ideas, how to do this?
Maybe I could find a solution, in existing gdsl, but I can't remember any Transformation, related to constructors. Maybe you can remind me of any of them.
def objectContext = context(ctype: "java.lang.Object")
contributor(objectContext) {
if (hasAnnotation("com.xseagullx.SomeAnnotation")) {
// Here I want to add constructor's declaration(with empty arg's)
// …
// And then my methods.
method name: 'someMethod', type: 'void', params: [:]
}
}
EDITED: OK, if it's as #jasp say, and there is no DSL construct for declaring Constructors, I'm still asking for a good documentation sources, other than JB's confluence page. Tutorials and other sources. I'm familiar with embedded dsl's for groovy, grails and gradle.
Need smth. more structured, if it's possible.
All function invocations inside of GroovyDSL are just calls to wrappers around internal IDEA's Program Structure Interface (PCI). However it doesn't cover all of PCI's abilities, including default constructors functionality I believe. One of an evidence for that is singletonTransform.gdsl, which is bundled into IDEA from 9 version and describes #Singleton AST transformation. Here is it's code:
contributor(context()) {
if (classType?.hasAnnotation("groovy.lang.Singleton")) {
property name: "instance",
type: classType?.getQualifiedName() ?: "java.lang.Object",
isStatic: true
}
}
As you can see it doesn't change a constructor and it's visibility, so IDEA will autocomplete this invalid code:
#Singleton class Foo {}
def foo = new Foo()
Futhermore GDSL that describes the semantics of GroovyDSL (which is actually the part of /plugins/groovy/resources/standardDsls/metaDsl.gdsl of IDEA sources) doesn't provide any ability for describing of constructors.
In this case I suggest you use newify transformation which allows you to describe targetClass.name method returning created instance.
I know this is a bit old, but I found myself looking for something similar.
The DSL you are looking for is
method params: [:], constructor: true although I don't understand why you'd need it; if a class doesn't declare any constructors doesn't IDEA always suggest the default one?
I fell in love with Groovy and try to use it more and more. Now I have to work with Oracle Forms Jdapi library. When working with this library, you write a lot of code like this:
JdapiIterator progIterator = getWorkForm().getProgramUnits();
while(progIterator.hasNext()) {
ProgramUnit currProgUnit = (ProgramUnit) progIterator.next();
...
}
and of cource I would like to write
getWorkForm().programUnits.each {
...
}
However, I never wrote a Groovy interface to an existing Java library and need some assistance. I know about Groovy 2.0's extension methods, but in that case I am thinking about a class with the same name in a different namespace which delegates only to the functions I would like to keep.
What is the best approach for providing the each functionality, but also all other closures applicable for collections? I would appreciate if you point me in the right direction!
The only method you need to provide is the iterator() method. You then get all of the Groovy Object iteration methods (each(), find(), any(), every(), collect(), ...) for free!
Hi I have the following Code Snippet;
class StringCalci
{
static def plus(Integer self, Integer Operand)
{
return self.toInteger() * Operand.toInteger()
}
}
use (StringCalci)
{
println("inside the Use method!")
println( 12 + 3 )
}
println(12+3)
I was been shocked to see the use of Use in groovy. The thing is this I can add methods to the Class at run-time(my own methods).when I was looking at the above code, I was Thinking how does Groovy make things possible like this! The use of println inside the Use is multiplying the two given numbers(because I have Override the plus method) , where as the outside println adds it! My question is how does Groovy recognise the println executes in Use and println outside the Use. Is Use is a keyword/method? I need to understand behind the scenes of this process.. Please let me know :)
Thanks in Advance :)
Welcome to the wonderful world of dynamic languages where everything is possible and nothing is certain!
This feature is called Categories. As for the implementation:
use is in fact not a keyword but a method which the Groovy runtime adds to the Object class, which makes it available everywhere.
I think the functionality is implemented mainly in the class GroovyCategorySupport
Judging from the Javadoc, it's based on keeping a map of overriden methods in a ThreadLocal which is then consulted for every method call.
yeah, that's not so great for performance, but so are pretty much all the dynamic "magic" features that Groovy and similar languages offer (and there's lots of them).