google / auto

A collection of source code generators for Java.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Implement abstract "with-" methods in the value class

kevinb9n opened this issue · comments

It is a somewhat well-known pattern that a "withPropertyName(...)" method in an immutable class returns a copy of that instance with only that one property changed.

Users can write these themselves, but:

  • It's really gross if you're not using the builder option
  • It's also gross just that there are two different ways you have to do it based on whether you use a builder or not
  • And we should note that even in the best case, where you use your own builder, a builder will be allocated and thrown away somewhat unnecessarily

We could add a feature saying that you can define these "with-er" methods as abstract methods and AV will implement them.

But.... if this is a feature that 1% of all value classes will ever use, I'd probably prefer we hadn't bothered with it. (Though granted, it's not the kind of feature that means more documentation; we feel the with- example needs to be documented either way so it actually simplifies the docs.)

👍 👍
"with-er"s are the bare minimum to make functional programming in Java practical in business-related code.

When using builders you could also have a way to create/init a builder from a value and use the builder setters to overwrite values.

That said, it looks like this could be done as an extension, right?

That's a good point, this could certainly be done with an extension.

On Tue, Dec 1, 2015, 2:57 AM Thomas Broyer notifications@github.com wrote:

When using builders you could also have a way to create/init a builder
from a value and use the builder setters to overwrite values.

That said, it looks like this could be done as an extension, right?


Reply to this email directly or view it on GitHub
#294 (comment).

I am attempting to implement "wither" extension however I hit this block:

if (method.getParameters().isEmpty() && method.getReturnType().getKind() != TypeKind.VOID) {

The processor does not consider methods with parameters as implementable. How would you around this limitation?

It looks like a toBuilder() would work here (at the expense of creating a new object at runtime compared to withers; amortized as soon as you want to change more than one value though)

That doesn't stop you from implementing those methods in an extension. As an example auto-value-parcel implements this abstract method void writeToParcel(Parcel dest, int flags).

@gabrielittner it does not stop me however I would like to get a method such as public abstract Test withA(String a) in the list of ExecutableElement from the Context. This is in order to read the method'sVariableElement(String a) so I can easily implement appropriate method without much hacking.

@gabrielittner awesome! It would be nice if any annotations and modifiers were retained (not force with methods to be public).

@eleventigers Check out @gabrielittner's auto-value-cursor implementation. The applicable() method shows how he was able to get the ExecutableElement from the context, complete with modifiers.

The AutoValue code you linked to, and what's given to the extensions in the list, are actual properties, i.e. the items that AutoValue is meant to create. If you have other methods they aren't properties, they're just methods, so I wouldn't expect those to appear in the properties collection.

@eleventigers Changed it. If you find anything else feel free to open an issue.

Let's close this in favor of @gabrielittner's extension.