Thursday, January 26, 2012

Dart Setters and Getters

‹prev | My Chain | next›

I remain stuck without a proper web development environment (c'mon Apple geniuses!), so tonight I continue to explore some Dart internals. I played about with factory constructors last night, and have to admit they are pretty darn cool. Tonight, I take a look at setters and getters.

On the face of it, setters and getters in objects is a pretty simple thing. Instead of needing full blown method syntax to retrieve a value:
var bob = new Person("Bob");
bob.greeting(); // => "Howdy, Bob!"
In Dart, we should be able to do something like:
var bob = Person.new("Bob");
bob.greeting; // => "Howdy, Bob!"
It is a simple enough thing, but over the long haul, removing parenthesis can only help with readability / maintainability.

So let's see if I know how to do this:
class Person {
  var name;
  var _greeting_opening = "Howdy";

  Person(this.name);

  get greeting() => "${_greeting_opening}, ${name}!";
}
I declare two instance variables--one public, one private--to hold the name of the person and the word used to open the greeting. My constructor is simple enough (assign the supplied string as the name of the person), so the constructor declaration can make use of the nifty Dart shortcut that assign the argument to an instance variable.

Lastly, I declare a greeting method that puts the two variables together in a string. Here again, I have a simple method, so I can use the compact () => function syntax.

To use this class, I print out the greeting to two different people:
main() {
  var bob = new Person("Bob")
    , alice = new Person("Alice");

  print(bob.greeting);
  print(alice.greeting);
}
Running this results in:
$ dart setters_getters.dart
Howdy, Bob!
Howdy, Alice!
What I really like about this is that I do not have to follow a convention for these beasties (e.g. getGreeting, setGreeting). I never stick with whatever convention I start and end up with way too much confusion over a simple thing.

Setting things is similarly easy in Dart. In the class defintion, I need to use set instead of get. The usage of setters looks like any other property being assigned:
bob.greeting = "Yo, Bob!";
To make this work, the class would then need the set method:
class Person {
  var name;
  var _greeting_opening = "Howdy"
    , _full_greeting;

  Person(this.name);

  get greeting() {
    (_full_greeting != null) ?
      _full_greeting :
      "${_greeting_opening}, ${name}!";
  }
  set greeting(greeting) {
    _full_greeting = greeting;
  }
}
I have introduced a new, private instance variable _full_greeting. If set, the greeting getting will use this as the return value, otherwise it will stick with the regular "Howdy <<your name here>>!" version.

When I run this code:
main() {
  var bob = new Person("Bob")
    , alice = new Person("Alice");

  print(bob.greeting);
  print(alice.greeting);

  bob.greeting = "Yo, Bob!";
  print(bob.greeting);
}
I am greeted with:
null
null
null
Ah. I missed a return statement:
class Person {
  var name;
  var _greeting_opening = "Howdy"
    , _full_greeting;

  Person(this.name);

  get greeting() {
    return (_full_greeting != null) ?
      _full_greeting :
      "${_greeting_opening}, ${name}!";
  }
  set greeting(greeting) {
    _full_greeting = greeting;
  }
}
Now, I get:
Howdy, Bob!
Howdy, Alice!
Yo, Bob!
Of course, the real fun starts when you begin making calculations based on setters:
  set greeting(greeting) {
    var parts = greeting.split(',');

    if (parts.length == 2) {
      _greeting_opening = parts[0];
      name = parts[1].replaceAll(' ', '').replaceAll('!', '');
    }
    else {
      _full_greeting = greeting;
    }
  }
Running the following:
main() {
  var bob = new Person("Bob")
    , alice = new Person("Alice");

  print(bob.greeting);
  print(alice.greeting);

  bob.greeting = "Yo, Fred!";
  print(bob.greeting);
  print(bob.name);

  alice.greeting = "Yo, yo, yo, Alice!";
  print(alice.greeting);
  print(alice.name);
}
Results in:
Howdy, Bob!
Howdy, Alice!
Yo, Fred!
Fred
Yo, yo, yo, Alice!
Alice
(try.dartlang.org)


There is some definite power there.


Day #276

No comments:

Post a Comment