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

Improve setters and getters examples on 'Methods' page #5759

Open
1 task
dtonhofer opened this issue Apr 29, 2024 · 0 comments
Open
1 task

Improve setters and getters examples on 'Methods' page #5759

dtonhofer opened this issue Apr 29, 2024 · 0 comments
Labels
a.language Relates to the Dart language tour e2-days Can complete in < 5 days of normal, not dedicated, work from.page-issue Reported in a reader-filed concern p2-medium Necessary but not urgent concern. Resolve when possible.

Comments

@dtonhofer
Copy link

Page URL

https://dart.dev/language/methods/

Page source

https://github.com/dart-lang/site-www/tree/main/src/content/language/methods.md

Describe the problem

At

https://dart.dev/language/methods#getters-and-setters

we read about getters and setters but the text feels much too short and the example could be extended (the example code also does not really tell a good story, IMHO).

Suggesting more examples to illustrate various setter/getter "do's" and "don'ts" (including one involving a final field that creates a recursive call, see below) that tell a more structured story. Especially for people coming from Java (like me) this is helpful.

Note on terms: I am using "synthetic field" for a setter/getter that simulates the presence of field, not sure whether this is the correct term.

Here we go:

import 'dart:math';

// A class with some fields.

class Example {

  int a;

  int _b;
  final int c;
  static int d = 1000;

  Example(this.a,this._b,this.c);

}

// You will get default getters and setters on class "Example":

void handleExample() {
  final ex = Example(1,2,3);
  // There will be a setter and getter for field "a".
  final v = ex.a;
  ex.a = 10;
  ex.a++;
  assert(ex.a == 11);
  // There will be a setter and getter for field "_b".
  // But both are not visible outside of the library (this file)
  final u = ex._b;
  ex._b = 20;
  assert(ex._b == 20);
  // There will be a getter and getter for field "c", but no setter.
  final w = ex.c;
  // ex.c = 10; // NO! "'c' cannot be used as a setter"
  // There will be a static getter and getter for static field "d".
  final z = Example.d;
  Example.d = 10;
  Example.d++;
  assert(Example.d == 11);
}

// You cannot override a getter or setter with a method.
// Moreover, the actual setter name for field "a" is really "a="
// instead of "a". "a=" is not a valid name for a manually written
// method, so you cannot even name the setter (that's how I understand
// it at least.)

class ExampleFaulty extends Example {

  // Both
  // ExampleFaulty(super.a, super.b, super.c);
  // and
  // ExampleFaulty(super.a, super._b, super.c);
  // work here.

  ExampleFaulty(super.a, super.b, super.c);

  // This will NOT compile:

  int a() {
    return a;
  }

  // This will NOT compile:

  void a(int x) {
    a = x;
  }

}

// You can define Java-style getX() and setX() methods.
// They are just common methods, nothing special.

class ExampleJavaStyleGetterSetter extends Example {

  ExampleJavaStyleGetterSetter(super.a, super.b, super.c);

  int getA() {
    return a;
  }

  void setA(int x) {
    a = x;
  }
}

// You can override the default setter and getter of a field
// in a subclass. There is a function syntax and a standard syntax
// to do that.

class ExampleOverrideGetterSetterOfA1 extends Example {

  ExampleOverrideGetterSetterOfA1(super.a, super.b, super.c);

  set a(int x) => a = x;
  int get a => a;
  
}

class ExampleOverrideAccessorsOfA2 extends Example {

  ExampleOverrideAccessorsOfA2(super.a, super.b, super.c);

  set a(int x) {
    print("Setter for 'a' has been called");
    a = x;
  }

  int get a {
    print("Getter for 'a' has been called");
    return a;
  }

}

// You CANNOT override the implicit setter and getter of a non-final field.
// in the same class (as opposed to in a superclass.) You will get a
// "duplicate_definition" error ("The name 'a' is already defined")

class ExampleFaultyOverridingGetterSetter {

  int a = 1;

  // Both of these will NOT compile:
  
  set a(int x) => a = x;

  int get a => a;

  // Both of these will NOT compile either:

  set a(int x) {
    a = x;
  }

  int get a {
    return a;
  }
}

// You SEEMINGLY can add a setter for a final field!
// But this is actually just an endless recursive call
// that will lead to a stack overflow.

class ExampleOverridingSetterOnFinalField {

  final int a = 1;

  // DON'T DO THIS, even if it compiles!

  set a(int x) => a = x;

}

// You can have a setter and getter for a "synthetic field",
// here the "opposite" of "angle", rotated by Pi (180°)

class ExampleSyntheticField {

  double angle = 0.0;

  static double _canonicalize(double x) {
    if (x >= 0.0) {
      return x.remainder(2.0*pi);
    }
    else {
      return 2*pi + x.remainder(2.0*pi);
    }
  }

  double get opposite => _canonicalize(angle + pi);
  set opposite(double x) => angle = _canonicalize(x - pi);

}

// The following output is produced by the example code:
// The opposite of 0.5 π is 1.5 π
// If the opposite is 0.5 π, the angle is 1.5 π
// If the opposite is 0.7499999999999997 π, the angle is 1.75 π

void handleExampleSyntheticField() {
  final ExampleSyntheticField obj = ExampleSyntheticField();
  obj.angle = 0.5 * pi;
  print("The opposite of ${obj.angle/pi} π is ${obj.opposite/pi} π");
  obj.opposite = 0.5 * pi;
  print("If the opposite is ${obj.opposite/pi} π, the angle is ${obj.angle/pi} π");
  obj.opposite += 0.25 * pi;
  print("If the opposite is ${obj.opposite/pi} π, the angle is ${obj.angle/pi} π");
}

void main() {
  handleExample();
}

Expected fix

No response

Additional context

No response

I would like to fix this problem.

  • I will try and fix this problem on dart.dev.
@dtonhofer dtonhofer added the from.page-issue Reported in a reader-filed concern label Apr 29, 2024
@atsansone atsansone added a.language Relates to the Dart language tour p2-medium Necessary but not urgent concern. Resolve when possible. e2-days Can complete in < 5 days of normal, not dedicated, work labels May 6, 2024
@atsansone atsansone changed the title [PAGE ISSUE]: 'Methods' needs more (or maybe more informative) examples for setters and getters Improve setters and getters examples on 'Methods' page May 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
a.language Relates to the Dart language tour e2-days Can complete in < 5 days of normal, not dedicated, work from.page-issue Reported in a reader-filed concern p2-medium Necessary but not urgent concern. Resolve when possible.
Projects
None yet
Development

No branches or pull requests

2 participants