0

Is there any trick to print the address of a dart object? I'm having an issue in which I have a standard enum class as described in Does Dart support enumerations?.

class Access {
  static const IA = const Access._(0);
  static const RO = const Access._(1);
  static const RW = const Access._(2);
  final int value;
  const Access._(this.value);
...
}

The variable access is of type Access and the value is 1, yet access==Access.RO is returning false.

var access = _.access;
print('''
access => ($access, ${access.runtimeType}, ${access.value})
static => (${Access.RO}, ${Access.RO.runtimeType}, ${Access.RO.value})
equal ? => ${(access == Access.RO)}
''');

prints

access => (RO, Access, 1)
static => (RO, Access, 1)
equal ? => false

If I provide an operator==(Access other) that compares the values it returns the expected value. So, I figured maybe this has to do with coming at the class from different libraries (maybe isolate related) and if I could print the address of access and Access.RO I could see if they are different. Of course, if they were different I'd then need to know why as well.

Community
  • 1
  • 1
user1338952
  • 3,233
  • 2
  • 27
  • 41

2 Answers2

2

When you deal with const you have to be very careful. If you use new Access._(0) instead of const Access._(0) you will not get the same object. Here is an example :

class Access {
  static const IA = const Access._(0);
  static const RO = const Access._(1);
  static const RW = const Access._(2);
  final int value;
  const Access._(this.value);
}

main(){
  print(Access.IA == const Access._(0));  // prints true
  print(Access.IA == new Access._(0));  // prints false
}

This could explain your problem.

Florian Loitsch
  • 7,698
  • 25
  • 30
Alexandre Ardhuin
  • 71,959
  • 15
  • 151
  • 132
  • Good point - but not the issue, since I do not 'new' them. (In fact - disabling new would be nice). Turns out the app used a library by importing the dart file directly. The library was also pulled in using import package: syntax. They resolved to same file but came in twice. The very nice --print_classes option made it clear. A feature request for dart might be determine uniqueness of library by full location of file pulled in. So, in both scenarios the print address of instance function would shed light. Can it be done? – user1338952 Apr 05 '13 at 16:34
  • Unfortunately I don't know if it's possible. – Alexandre Ardhuin Apr 05 '13 at 16:54
1

If identical(a, b) returns false you can be sure that their pointers are different. (The inverse is not necessarily true for numbers, but that's an implementation detail).

If you are dealing with isolates you need to be careful when you transmit objects. Even, if they are canonicalized on one side, they won't be, after they have been transmitted to another isolate:

import 'dart:async';
import 'dart:isolate';

class A { const A(); }

foo() {
  port.receive((x, _) {
    print(x == const A());  // Prints false.
  });
}

main() {
  var p = new ReceivePort();  // To keep the program running.
  spawnFunction(foo).send(const A(), null);
}

Also note that dart2js doesn't allow to transmit arbitrary objects.

Florian Loitsch
  • 7,698
  • 25
  • 30
  • Given that, with the enum idiom, it probably makes sense to provide an operator== that checks the actual value, rather than rely on oject.operator==? In this case that would be safer. But then, that would not help in situations where the named constant enum value were used in a switch statement? – user1338952 Apr 05 '13 at 18:37
  • I wouldn't overwrite the '==' operator. If you only have a limited set of instances you actually want an identity comparison (which is probably faster too). – Florian Loitsch Apr 05 '13 at 19:25