Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement abstract "with-" methods in the value class #294

Closed
kevinb9n opened this issue Dec 1, 2015 · 12 comments
Closed

Implement abstract "with-" methods in the value class #294

kevinb9n opened this issue Dec 1, 2015 · 12 comments

Comments

@kevinb9n
Copy link
Contributor

kevinb9n commented Dec 1, 2015

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.)

@jbgi
Copy link

jbgi commented Dec 1, 2015

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

@tbroyer
Copy link
Contributor

tbroyer commented Dec 1, 2015

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?

@rharter
Copy link
Contributor

rharter commented Dec 1, 2015

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).

@eleventigers
Copy link

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?

@tbroyer
Copy link
Contributor

tbroyer commented Jan 14, 2016

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)

@gabrielittner
Copy link

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).

@eleventigers
Copy link

@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
Copy link

I've created a quick implementation https://github.com/gabrielittner/auto-value-with

@eleventigers
Copy link

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

@rharter
Copy link
Contributor

rharter commented Jan 14, 2016

@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.

@gabrielittner
Copy link

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

@ronshapiro
Copy link
Contributor

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants