„destructuring assignment“ – like the subject said – would make more sense in a more complex scenario:
(inspired by Perl)
var { name, firstname, adress } = person;
resulting in
var name = person.getName();
var firstname = person.getFirstname();
var adress = person.getAdress();
With this, the chosen variable name must fit with an existing getter.
But if Lombok should „implement some magic logic“, the original code must be valid Java code.
I am not sure about the language spec, but I think that somple is invalid.
Maybe more:
@Destruct(„name“, „firstname“, „adress“) person; // basically an empty instruction; maybe Lombok could replace this by the code block above
System.out.printf(„%s, %s: %s%n“, name, firstname, adress);
Jan
--
You received this message because you are subscribed to the Google Groups "Project Lombok" group.
To unsubscribe from this group and stop receiving emails from it, send an email to project-lombo...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/project-lombok/8ffedb2c-4b44-4ff8-8b99-eaf0e055516dn%40googlegroups.com.
public static void main(String[] args) {
var person = new Object();
var { name, firstname, adress } = person;
}
Syntax error on token "}", Expression expected after this token
public static void main(String[] args) {
var a,b,c ="";
}
'var' is not allowed in a compound declaration
public static void main(String[] args) {
var person = new Person("me");
var o = person.conStruct();
out.prinln(o.name);
}
Playing with possible syntax this would work on Java 17:
public class LombokTest {
public static void main(String[] args) {
Object person = null;
@Deconstruct({"name", "lastname", "adress"}) var unused = person;
System.out.println("Runs fine");
}
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
@java.lang.annotation.Target(java.lang.annotation.ElementType.LOCAL_VARIABLE)
public @interface Deconstruct {
String[] value();
}
}
Because the given value() must fit to the getter, you could also introduce a name mapping:
@Deconstruct({"name", "lastname", "postadress:getAdress"}) var unused = person;
// var name = person.getName();
// var lastname = person.getLastname();
// var postadress = person.getAdress();
To view this discussion on the web visit https://groups.google.com/d/msgid/project-lombok/0c270501-cfa9-4be6-a199-b9cda5212d4en%40googlegroups.com.
„destructuring assignment“ – like the subject said – would make more sense in a more complex scenario:
But if Lombok should „implement some magic logic“, the original code must be valid Java code.
I think the idea is good but the issue I can think of is, is that even java syntax ? Can we have an array assignment as a var declaration ?
The best I can think of, is a lombox method to extract all the instance fields in a constant structure.
Your Pojo fields are private. What's more they can be retrieved at execution time, so varying.
You received this message because you are subscribed to a topic in the Google Groups "Project Lombok" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/project-lombok/AWx5uDsX6mQ/unsubscribe.
To unsubscribe from this group and all its topics, send an email to project-lombo...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/project-lombok/3db23e2f-80b4-4ee3-a68d-592168eabf73n%40googlegroups.com.
I know what you want to do. There is no confusion. Were you to access your pojo fields through the accessors or not does not change that they can be changed between calls.Again,Do you have an example where this would be actually useful and not bug-prone ?So far you want to have```java{// MyMap::new(java.util.Map backing, String owner)MyMap<?,?> m = new MyMap(new HashMap<>(Map.of("a", "b")), "me");var hashCode = m.hashCode();var size=m.size();var owner=m.getOwner();}```replaced by```java{// MyMap::new(java.util.Map backing, String owner)MyMap<?,?> m = new MyMap(new HashMap<>(Map.of("a", "b")), "me");@Deconstruct({"hashCode:hashCode", "size:size", "owner"}) var unused=m;}```
And I'm saying this is bug-prone because if I replace "owner" by "creator" I won't know why it fails later.
OR if I used it twice for comparison, the second call :` @Deconstruct({"hashCode:hashCode", "size:size", "owner"}) var unused=m2; `will fail because "unused" already exists, or the variables already exist, which will become tedious to handle.
Meanwhile, using a constant structure method in the class allows to avoid both those issues.
To view this discussion on the web visit https://groups.google.com/d/msgid/project-lombok/6c25c225-8751-4764-8006-a836c3289ab6n%40googlegroups.com.
Thanks for clarifying your needs.
But just for getting rid of one getter-call I think this is not worth the effort.
Additionally you have to use the special name for your local variable so it fits to the getter.
This means, that refactoring (rename the getter) or the local variable is not possible.
Having multiple calls is also not possible:
Person p1;
Person p2;
var name = p1;
var name = p2;
// need names of p1 and p2 ???
„I have a pojo (sometimes a JPA entity, sometimes a DTO, generally speaking an object full of getters and setters) and I need to extract 3/4 fields to implement my business logic.
In more than one case, I need to access the field values twice or more, so I usually keep them in local variables for the lifetime of the method.“
I dont see any benefit in holding the value in a local variable over using the getter.
You would have some if the „getter“ is expensive by calculating/loading stuff (in that case it is not a ‚real‘ getter) or if you need the „first value“ and the field is changed in the meanwhile.
If you want to transfer a bunch of values from one pojo to another I recommend a mapping framework like MapStruct.
To view this discussion on the web visit https://groups.google.com/d/msgid/project-lombok/CAGxu5EcVpHoYr1zLMmXxOoJnQ5o8SaLX4ho2KD-xiqUkBU-e_w%40mail.gmail.com.
Thanks for clarifying your needs.
But just for getting rid of one getter-call I think this is not worth the effort.
Additionally you have to use the special name for your local variable so it fits to the getter.
This means, that refactoring (rename the getter) or the local variable is not possible.
Having multiple calls is also not possible:
Person p1;
Person p2;
var name = p1;
var name = p2;
// need names of p1 and p2 ???
To view this discussion on the web visit https://groups.google.com/d/msgid/project-lombok/00a701d9f202%24570015a0%24050040e0%24%40gmail.com.
> well, first of all... that is NOT what I want.And that I would know if you had answered me about an actual example where this would be useful and not bug-prone.
> and my goal is just to support getters.Getters in lombok have options (eg fluent) that make your original idea not usable in many cases.
> Compile errors will occur (and at least eclipse tells me instantly)It won't. There is a thing called "refactoring" on most IDEs. You don't change the names by hand, you refactor them.
> And in this scenario your suggestion to create another object with a `.foo` field doesn't help me... I should write something likeNo. You write something like :// actual logic that relies on o.foo, o.bar, o.baz> I dont see any benefit in holding the value in a local variable over using the getter.You have some if the access is lazy on a DB and the new construction is done in // .For example if the Book have Person as authors, and Student have Person as teachers, then listing the students and the books of a Person should be done in // .Something like```@Get("byId/{id}/stats")public PersonDTOOut getStatsById(@PathParam long id){Person p = personService.findById(id);// omit checksPersonDTOOut dto = new PersonDTOOut();Person.ConStruct pc = p.conStruct();dto.numberOfBooks = pc.books.size();dto.numberOfStudents=pc.students.size();dto.numberOfChildren=pc.children.size();dto.numberOfHouses=pc.houses.size();return dto;}```
To view this discussion on the web visit https://groups.google.com/d/msgid/project-lombok/4b484769-518c-4f93-9c6b-7c3423ebcde5n%40googlegroups.com.
class Person {
@Getter(lazy=true)
private final List<Book> books=fetchBooksFromDB();
private List<Book> fetchBooksFromDB() {
// access the DB, typically with service or direct DB query
return null;
}
// other fields that require a DB access
// the rest is built by lombok :
@AllArgsConstructor
public static class ConStruct{
public final List<Book> books;
}
public ConStruct conStruct(){
// future for a field, associated to its accessor
Future<List<Book>> f_books = ForkJoinPool.commonPool().submit(()->getBooks() );
// other accessors and futures
// ...
try {
return new ConStruct(
f_books.get()
// access the other futures
);
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
}
> what doubt do you have about this simple description? Do you get that my goal was just to avoid the repetition of "foo" and "getFoo"?Well … it's useless. I asked for a *useful* and error-prone use case.
To view this discussion on the web visit https://groups.google.com/d/msgid/project-lombok/6c2d49a0-dac7-4e87-b1ca-2a6a25915fe2n%40googlegroups.com.
On 30. Sep 2023, at 21:23, Marco Servetto <marco.s...@gmail.com> wrote:lambdas are valid Java syntax, right?
so to write
var {firstName, lastName, gender, birthDate} =
databaseConnection.fetchPersonByID(id);
we can just write
(firstName,lastName,gender,birthDate)->databaseConnection.fetchPersonByID(id);
Would this work? or are lambdas are valid expressions but not valid statements?
On 1. Oct 2023, at 01:15, guillaume LE LOUËT <guillaum...@gmail.com> wrote:
> Guillaume, I have not the slightest idea how what you wrote relates to this feature here, so maybe that discussion on whatever you are proposing should be continued in a separate thread.
What I wrote before was an example of when the example discussed is actually useful. Because as you wrote, and as Vito wrote, writing @Destruct var firstName = person is completely useless(should write var fistName = person.getName() ) , ...
... and all the other examples that were provided were non valid java syntax.
> so maybe that discussion on whatever you are proposing should be continued in a separate thread.My answer was considering the issue of name clash. Since the original proposal creates new variables with the names of the fields, if you use it while names are already assigned to variables, then this would not work.This WILL happen if you use it twice, for example for comparison of two items, or if the variables are already present eg as parameters, therefore this initial idea is fundamentally bugged.
Someone else addressed it using name mapping in the annotation params but this will provoke bugs when refactoring.
My proposal was to place the annotation on the POJO , making a constant class that can be access using "." notation. It fixes clash and refactoring issue (also valid syntax issue) but it requires to modify the POJO which may not be possible.This IS on topic as a way to acquire all the fields in a easily accessible manner without injecting compiling/usage bugs, with annotations.This IS NOT on topic considering POJOs you can't modify - just like constructors, accessors in lombok.
> it is not quite clear to me what constitutes "valid Java syntax".valid syntax means that the java compiler must not find a syntax error before lombok modifies the instructions tree.
--
You received this message because you are subscribed to the Google Groups "Project Lombok" group.
To unsubscribe from this group and stop receiving emails from it, send an email to project-lombo...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/project-lombok/17240728-5f0e-4fed-975c-7488561a451en%40googlegroups.com.
Maybe this could be easier to actually implement?@Destructure
var firstName, lastName, gender, birthDate = databaseConnection.fetchPersonByID(id);
@Getter
Object pos1;
@Deconstruct(prefix = "d_", suffix="_s") Object title, author=book;
@Deconstruct(prefix = "b2_") Object title, author=book2;
Objects.equal(b1_title, b2_title);
I recommend beginning with a basic implementation first. Additional features, such as prefixes, can be added in later versions. I believe the syntax is quite solid. Perhaps adding curly braces around the object to be deconstructed could be considered. Alternatively, you could explore the possibility of introducing a dedicated type (e.g., "deconstruct") that would then resolve to var.
variable.type = (JavacHandlerUtil.chainDots(varNode, "lombok", "var")).type;
I believe we should accommodate two primary getter styles: 'get/is' and 'fluent.' We don't need to include support for unconventional prefixes; instead, we can utilize an enum to specify the supported styles.
When implementing new features, it's important to keep in mind that we won't be able to easily remove them after a release. Many developers use Lombok, so the design should be well-considered and as clear and understandable as possible.
Book mybook = new Book("author0", "bookname0", new Date(), true);
@Onstruct
Object author, editionDate = mybook;
@Onstruct(methodPre = "")
Object name = mybook;
@Onstruct(methodPre = "is")
Object purchasable = mybook;
@Onstruct
Object author// var author = mybook.getAuthor()
, editionDate = mybook;// var editionDate = mybook.getEditionDate()
@Onstruct(source=SourceType.FLUENT)
Object name = mybook;// var name = mybook.name()
@Onstruct(source=SourceType.BOOL)
Object purchasable = mybook;// var purchasable = mybook.isPurchasable()
@Onstruct(source = SourceType.FLUENT, methodCml = Cml.CML)
Object name=mybook; // var name = mybook.Name()
@Onstruct(source = SourceType.FLUENT, methodPre = "make", suf = "_2")
Object name=mybook; // var name_2 = mybook.makename()
To view this discussion on the web visit https://groups.google.com/d/msgid/project-lombok/962ba610-b762-4903-8a91-de722deb2969n%40googlegroups.com.