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

feat: copyWith methods for all classes #853

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open

feat: copyWith methods for all classes #853

wants to merge 1 commit into from

Conversation

g123k
Copy link
Contributor

@g123k g123k commented Dec 11, 2023

Hi everyone!

Instead of limiting ourselves to the Product class, I've added the copyWith method to all classes, except when:

  • There is an empty constructor
  • There is a private constructor

@g123k g123k requested a review from a team as a code owner December 11, 2023 14:17
@g123k g123k linked an issue Dec 11, 2023 that may be closed by this pull request
@g123k g123k changed the title copyWith methods for all classes feat: copyWith methods for all classes Dec 11, 2023
Copy link
Contributor

@monsieurtanuki monsieurtanuki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @g123k!

  • I don't believe in "just in case" code, that nobody asked for and that we'll I'll have to maintain, cf. here 38 files out of 39
  • your implementation of copyWith is misleading as you're not really copying data - that could be OK for int and String but not for Map<String, String> that is passed by reference

Example:

class Toto{
  Map<String, String>? map;
  
  Toto({this.map});
  
  Toto copyWith({
    Map<String, String>? map,
  }) {
    return Toto(
      map: map ?? this.map,
    );
  }
}

void main() {
  final Toto toto = Toto();
  toto.map = {'a': 'toto'};
  print(toto.map);
  
  final Toto titi = toto.copyWith();
  titi.map!['a'] = 'titi';
  print(toto.map);
}

Output:

{a: toto}
{a: titi}

That's partly why I used a combo of jsonDecode / jsonEncode to recreate objects from scratch. The second reason is that it's much easier to read and maintain. And performance is not an issue here.

@g123k
Copy link
Contributor Author

g123k commented Dec 13, 2023

True, you're right about the collections which are mutable.
The idea of my change to all classes is the fact that if we implement it for one class, we will have requests for others.
This change is purely a matter of consistency, but I also understand your point

@monsieurtanuki
Copy link
Contributor

True, you're right about the collections which are mutable.

So you agree that your code contains bugs, right?

The idea of my change to all classes is the fact that if we implement it for one class, we will have requests for others.

That's what I call "just in case" code, and I don't believe in it. Let's rather code "on demand": issues are made for that.
Especially given that we don't block developers that would really need those methods from coding them themselves: in Smoothie I coded a copy method and I was not blocked by the fact I was coding from another project.

This change is purely a matter of consistency, but I also understand your point

We agree that we disagree.

If you need an additional reason NOT to do that: in the specific case of Product that would probably be misleading to provide a "standard" copyWith method as it's not a "normal" class - many fields are read-only, and you cannot even save a product with just one method (there are 2 methods, one for packagings V3, the other for the other fields).

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

Successfully merging this pull request may close these issues.

Add a copyWith method to the Product object
2 participants