In groovy you got closure which I kinda get, (similar to js, and ruby blocks) but I came across this code and I would like some clarification.
def bar = {
-1
}
..
..
.
getResults foo, bar , params, Foo.class.simpleName
Which get getResults is a method that takes a closure bar as a parameter. What I don't get is that in the method it has this:
public int getResults ( foo, bar , params, classSimpleName) {
def totalCount = bar(params)
..
..
.
Now bar(params) returns -1 which is the value of it. But I dont get how it works.
is params a predefined word?
I am working in Grails and I know that my params passed to to controller, have no bar variable in them, and I dont know how they are related to this.
bar is a closure. You are invoking the closure with params parameter. bar closure does not care about any parameters. It always returns -1. That's it.
params is a predefined variable in grails controllers.
Related
I've been using attrs the following way:
#attr.mutable
class Foo:
x: int = attr.ib(validator=attr.validators.instance_of(int))
#attr.mutable
class Bar:
x: int = attr.ib(validator=attr.validators.instance_of(int))
foo: Foo = attr.ib(
default=attr.Factory(factory=lambda self: Foo(self.x), takes_self=True),
validator=attr.validators.instance_of(Foo),
)
if __name__ == "__main__":
Bar("5")
When I ran the code, I obviously got an error.
But, the not intuitive part for me was that the validator of the Foo class raised the error.
I may be wrong but according to this I assume that validator of the x attribute of the Bar comes after Foo's.
Why is that? Would not it make more sense to validate Bar's x attribute before passing it as an argument to Foo's init method?
Thanks in advance!
When instantiating, defaults are filled before the validators run.
The __init__ method doesn't know anything about the fact that Foo has a validator and Foo doesn't know, that Bar hasn't fully instantiated itself.
From the perspective of Bar, it calls the factory with the value of x that hasn't been validated yet ("5").
From the perspective of Foo, it gets instantiated with a str and fails validation.
Say I have a class with variable var1. I click on a button & it calls pageLoadMethod() which loads the page and inside it I set var1 to 10.
Now I click on another button after page is loaded ajaxMethod() & try to retrive var1 value but not getting it's value set in
pageLoadMethod() method.
Class MyClass{
def var1 = 1;
def pageLoadMethod(){
var1 = 10;
....
}
def ajaxMethod(){
println var1; // prints 1 instead of 10
}
}
The premise of this answer is that MyClass is a controller, which I assume from the context.
In Grails the controller instances are by default created for each request - that's why you don't see changed value of var1 in the ajaxMethod.
You can make a singleton from the controller by adding this line into it:
static scope = "singleton"
After this you should see the changed value in ajaxMethod.
Another question is if this is a good approach when multiple users can access your controller at the same time - if you want to use the variable to save some state between user's requests, you should rather use session for that..
I suppose MyClass is kind of controller. Whats the scope of this controller ? If You want to keep it's state between requests, you should use Session scope.
http://grails.org/doc/2.4.x/guide/single.html#controllersAndScopes
In Grails you can declare a controller action like this:
def create(Integer foo, Integer bar) {
}
And if your HTTP request has parameters named foo and bar with values that can be converted to an Integer, the parameters will be assigned these values. I'm wondering how Grails can do this, because my understanding is that at the JVM bytecode level, a method's formal parameter names are not available. Is this witchcraft or am I misunderstanding something?
Basically what happens is that there's an AST transform that adds a new method with no args and the same name. This new method has logic in it to do the data binding based on the declared types of your "real" method, and then call your method. That's why the types are required (otherwise there's no way to do a conversion) and why you cannot have method overloads.
The inability to have overloaded methods is easy to work around though. Say you wanted an action
def foo(String bar)
and another
def foo(String bar, Integer wahoo)
In this scenario just keep the 2nd method and check to see if wahoo is null.
It's also important to use object parameter types and not primitives. If you use int/long/boolean/etc. and there is no provided parameter, you would get a NPE (since zero is not an acceptable conversion from null for numbers, and either is false for booleans).
You can get a decent sense for what's going on if you decompile the class using JD-GUI or another decompiler.
The fact that Grails controllers are Groovy classes helps quite a lot. Looking through the source code for controllers you can see where it makes heavy use of AST transformations, in particular the MethodNode. So, before it becomes bytecode the "witchcraft" is done. :)
The title may be misleading. What I really want is to know the name of a closure within a controller. But closures in Groovy are always anonymous, so there is no name of the closure itself. But the closure is assigned to a variable, and I'm wondering if I can get the name of that variable. Perhaps an example will help. In a Grails controller imagine I have the following:
def get_data = {
Map results = [ 'errorCode' = -1, 'method' : 'get_data' ]
...
render results as JSON
}
In the Map called results there's an element called 'method' that I want to assign to the name of this closure (or variable holding the closure to be more precise). Is this possible? The idea here is I want to generalize the results map and want to automatically populate an element called 'method'. Instinctively it feels like this should be possible but I haven't found any similar use cases that illustrate how. Any help much appreciated.
I don't think that you can get name of the variable in the general case. This is only a reference, and the closure can be assigned to many of them.
It is very simple, however, to get name of the current action in the controller code:
def get_data = {
def results = ['method': actionName]
}
See documentation.
How do we retrieve the list of parameters of a closure/method in groovy dynamically, javascript style through the arguments array
say for example that i want to log a message this way
def closure = {name,id ->
log.debug "Executing method with params name:${} id:${id}"
}
OR
void method (String name,String id) {
log.debug "Executing method with params name:${} id:${id}"
}
I read once about a way to reference the list of parameters of a closure, but i have no recollection of that and looking at the groovy API for Closure reveals only getParametersType() method. As for the method, there is a way to call a method as a closure and then i can retrieve the method parameters
ken
You won't like it (and I hope it's not my bad to do research and to answer), however:
There is no API to access the list of parameters declared in a Groovy Closure or in a Java Method.
I've also looked at related types, including (for Groovy) MetaClass, and sub-types, and types in the org.codehaus.groovy.reflection package, and (for Java) types in the java.lang.reflect package.
Furthermore, I did an extensive Google search to trace extraterrestrials. ;-)
If we need a variable-length list of closure or method arguments, we can use an Object[] array, a List, or varargs as parameters:
def closure = { id, Object... args ->
println id
args.each { println it }
}
closure.call(1, "foo", "bar")
Well, that's the limitations and options!
The parameter names can be retrieved if the compiler included debugging symbols, though not through the standard Java Reflection API.
See this post for an example https://stackoverflow.com/a/2729907/395921
I think you may want to take a look at varargs http://www.javalobby.org/articles/groovy-intro3/