Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to make a static class value a method call like a getter property

I have this class:

export class Vec2 {
  static unit = new Vec2(1, 1)

  get clone(): Vec2 {
    return new Vec2(this.x, this.y)
  }

  constructor(readonly x: number, readonly y: number) {}


  scale(k: number) {
    this.x *= k
    this.y *= k
  }
}

I want to use it like this:

let ten_v = Vec2.unit.scale(10)
let twenty_v = Vec2.unit.scale(20)

As you can see I start from a unit vector and scale it to get the vector I want.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

This is the API I want no Vec2.unit() or Vec2.unit.clone.scale(10).

The problem with this is, scale method modifies the unit vector which is a static object, and I don’t want that.

So I would like a static getter property just like object instances have getter properties that expands into method calls. Like clone in this example but static.

>Solution :

If you’re targeting ECMAScript 2015 or higher (which you, let’s be honest, probably should be in 2022), you can actually just declare getters with the static modifier.

static get UNIT() {
  return new Vec2(1, 1);
}

But read on, because I want to challenge the frame of this question a bit. The frame challenge is this: Why is your vector mutable at all? Vectors are nice mathematical objects, so why not have all of those functions just return new ones?

export class Vec2 {
  static UNIT = new Vec2(1, 1);

  readonly x: number;
  readonly y: number;

  constructor(x: number, y: number) {
    this.x = x;
    this.y = y;
  }

  scale(k: number) {
    return new Vector(this.x * k, this.y * k);
  }

}

Now you don’t have to worry about whether or not existing vectors get modified, because vectors never get modified. You don’t need clone anymore, since there’s never a use case to intentionally have two identical-looking vectors. And the static field is fine since, again, everything you can possibly do to it is immutable.

I’ve been working with the Minecraft Bukkit API, and it has a mutable Vector class. So I can speak from personal experience when I say that it is a royal pain to work with. Every time you want to modify a vector, you defensively .clone because you’re not sure if the function you called just did that or not, and anytime you want to modify an existing vector, you end up assigning it back because, again, you’re not sure if they gave you the real vector or a clone. Sometimes it’s documented, but sometimes it’s not. So really, save yourself and everyone who uses your library the immense headache and just make it immutable.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading