Is there an equivalent in Dart of the instance_variable_set method in Ruby?

233 Views Asked by At

If not, is there anything like this on the horizon?

This is the one feature of JavaScript, Ruby, and Perl that I can't live without. I know you can fake it with a hash member, but I want to be able to create (arbitrary) "first class" members from a parser.

2

There are 2 best solutions below

3
On BEST ANSWER

Currently there's nothing that can set a field that doesn't yet exist. The mirror API can be used to set fields that already exist, and may eventually be extended to support defining new fields dynamically.

0
On

You can also use the "noSuchMethod" method on a class to intercept setter / getter, and store the received value in a map.

For example (I can't remember the syntax exactly...):

class Foo {
  var _dynamicProperties = new Map<String,Object>();

  noSuchMethod(String function_name, List args) {
    if (args.length == 0 && function_name.startsWith("get:")) {
      // Synthetic getter
      var property = function_name.replaceFirst("get:", "");
      if (_dynamicProperties.containsKey(property)) {
        return _dynamicProperties[property];
      }
    }
    else if (args.length == 1 && function_name.startsWith("set:")) {
      // Synthetic setter
      var property = function_name.replaceFirst("set:", "");
      // If the property doesn't exist, it will only be added
      _dynamicProperties[property] = args[0];
      return _dynamicProperties[property];
    }

    super.noSuchMethod(function_name, args)
  }
}

And then you can use this in your code as follows:

var foo = new Foo();
foo.bar = "Hello, World!";
print(foo.bar);

Of course, this can lead to typos that will not be checked by the type checker, e.g.:

foo.bar = "Hello";
foo.baz = "Hello, World!"; // Typo, meant to update foo.bar.

There are ways you have type-checker validation by using redirecting factory constructors and an implied interface, but then it starts to get complicated.

Side note: This is what JsonObject uses to convert a JSON map to a class type syntax.