I am new to Grails and beyond a little bit of PHP have little development experience. I'm looking for the best way to combine multiple strings I've been successful using the + operator as follows but am not sure if this is the most effective way. I tried sorting it out using StringBuilder but could not get it to work. Any examples showing that would also be appreciated.
class Person {
String firstName
String middleName
String lastName
static constraints = {
some constriants...
}
String toString() { return lastName + ',' + lastName + ' ' + middlename }
}
Try
return "$lastName,$lastName $middleName"
The Groovy language is very flexible for this improvements, I explain this:
In Java you have:
private String field;
public String toString(){
return "new String" + field;
}
In Groovy as you know the 'public' word is optional but also the keyword 'return' is optional too and we can use a GString implementing the $ operand
In Groovy you have:
String toString(){
"new String $field" // cool, uh
}
Is a lil' of syntactic sugar...
Regards
Related
I am new here and this is my first post. I recently got into touch with Jackson and i would like to know if it's possible to get other values than string (or int) while serializing. Pleae be kind if I confuse parts of the terminus.
For example: I have enum
public static enum Type {A, B, C}
in a class like
public class MyClass{
private Type charCat;
public Type getCharCat(){
return this.charCat;
}
public void setCharCat(Type t){
this.charCat = t;
}
}
But if I create an Object (for example with charCat A) and write it into a file I get
...
charCat: "A"
...
How could i get
...
charCat: A
...
?
I tried several tips and solutions, but they did not work.
I am not sure exactly what you are asking for, but the only valid kind of JSON would be
{ "charCat" : "A" }
as all textual values MUST be enclosed in double-quotes. Only values that do not need that are numbers, boolean values (true and false) and null. So serializing value as
{ charCat : A }
would not be valid JSON; so there is no way to get such output.
It seems sorting in Dapper Extensions can be achieved with Predicates:
Predicates.Sort<Person>(p => p.LastName)
My question is, how do I implement random sorting (i.e. RAND() in sql) to predicates?
Predicates.Sort actually produces an ISort-compatible interface which is defined as follows:
public interface ISort
{
string PropertyName { get; set; }
bool Ascending { get; set; }
}
It looks like we have a chance of setting property name to "RAND()" or something, right?... But, sadly, this interface is used in this way:
if (sort != null && sort.Any())
{
sql.Append(" ORDER BY ")
.Append(sort.Select(s => GetColumnName(classMap, s.PropertyName, false) + (s.Ascending ? " ASC" : " DESC")).AppendStrings());
}
So Dapper Extensions in fact check that the passed name is a column name. And the GetColumnName is defined as follows:
public virtual string GetColumnName(IClassMapper map, string propertyName, bool includeAlias)
{
IPropertyMap propertyMap = map.Properties.SingleOrDefault(p => p.Name.Equals(propertyName, StringComparison.InvariantCultureIgnoreCase));
if (propertyMap == null)
{
throw new ArgumentException(string.Format("Could not find '{0}' in Mapping.", propertyName));
}
return GetColumnName(map, propertyMap, includeAlias);
}
Therefore, the string actually should be not a column name, but a property name (they have named the field in ISort interface for a purpose, right?).
So, to implement something like the thing you want you need to customize their SQL generator.
For further details, the best way is to refer to sources:
Predicates: https://github.com/tmsmith/Dapper-Extensions/blob/master/DapperExtensions/Predicates.cs
SqlGenerator: https://github.com/tmsmith/Dapper-Extensions/blob/master/DapperExtensions/Sql/SqlGenerator.cs
PS: I am unable to post link to the repo root due to beginner's rep, hope you can guess it ;)
PPS: The same is true for whole predicates system in Dapper Extensions. I believe it should be greatly refactored to allow more than plain-forward column-based restrictions.
So can you please help me to understand what String toString() { "$email" } will do in the following program???
class User
{
Long id
Long version
String email
String password
String toString()
{ "$email" }
def constraints =
{
email(email:true)
password(blank:false, password:true)
}
}
It means that whatever is in the email variable will be returned when toString() is called.
It could also be written as:
#Override
String toString() {
email
}
but the writer decided to be "smart" (yes, I'm being sarcastic!) and use the $ notation of embedding a variable into a string.
Remark:
In groovy you don't have to use return - the default behavior is that the last statement inside a method will be returned.
I would like to make a macro that would essentially expand this:
#WithBasicConstructor
class Person {
private String name
private String address
}
into this:
class Person {
private String name
private String address
Person(String name, String address) {
this.name = name
this.address = address
}
}
I've been reading through the code for #Immutable to get a feel for how it is done. Has anyone used the new AstBuilder?
Any ideas how to implement this? Is there a preferred option between AstBuilder for string/code/spec ?
You could use (or copy) #groovy.transform.TupleConstructor from groovy 1.8.
Regarding preferences... I like the buildFromSpec, it leads to fewer surprises.
But I'd suggest you try the buildFromCode, test its limitations and quirks, play a little with all of them.
Today I had something weird happen in my copy of Resharper 5. I have a class that looks like this:
public class Foo
{
public string Username { get; private set; }
public Foo (string userName) { Username = userName; }
public void Bar()
{
DoWork(Username);
}
public void DoWork(string userName) { }
}
When I start to type DoWork(us I get the following from intellisense:
Notice that it's pulling up the constructor argument, and it ends with a colon: userName:
What's going on here?
EDIT:
As Reed answered below, this is a new C# 4 feature called Named and Optional Arguments. It's purpose is to allow you to specify the name of an argument, rather than it's position in a parameter list. so you don't have to remember the position of an argument in the argument list to use it (though this is largely meaningless with intellisense). It does make optional arguments easier to use though.
Thanks Reed.
This is Resharper providing intellisense support for Named and Optional Arugments.
C# 4 added support for these. You can now have a method defined like this:
public void DoWork(int someArgument = 3, string userName = "default")
{
// ...
If you want to call this with a different "userName" but leave the default for other parameters, you can do:
this.DoWork(userName: "FooUser");
Resharper 5 adds support for this syntax in intellisense.
You didn't include the ; at the end of userName
public Foo (string userName) { Username = userName; }