Saturday, May 10, 2014

Reflecting on Class, Reflecting on Object


I don't want to classify reflection in Dart as bewildering, but I confess to being a bit befuddled, at the least.

Let me be clear: I am not criticizing dart:mirrors. I know very little about reflection in static languages, but the little that I do know seems similar to what I see in Dart. In other words, this is probably just the nature of the beast that is reflection. Given that, I seek tonight to better understand reflection of classes—in particular the means to obtaining code information vs. obtaining a reference to the running code.

To obtain a reference to a runtime function, I reflect() on the function by name. To obtain an object that encapsulates the code as it was defined / declared, I can use a property of that reflected function (that property being the function property of a ClosureMirror).

As I found last night, things seem different with classes than functions. Instead of reflecting on a class to obtain a runtime mirror which has a property that points to the class's declaration mirror, there is the reflectClass(), which gives direct access to the code declaration. I am curious why this is the case—why doesn't reflect() on a class return an object reference that has a code declaration property?

To answer, I explore the InstanceMirror that is returned when reflect() is called on a class. If main() is a function and Foo is a class, then the following:
main() {
  print(reflect(main));
  print(reflect(Foo));
}
Will place the following on command output:
ClosureMirror on 'Closure: () => dynamic from Function 'main': static.'
InstanceMirror on Type: class 'Foo'
So what good is an instance mirror on class Foo?

There does not seem to be a way to create a new object from the class instance mirror:
main(){
  var fooMirror = reflect(Foo);
  var foo2 = new (fooMirror.reflectee)();
}
Produces:
$ dartanalyzer main.dart && dart main.dart
Analyzing main.dart...
[error] Expected a type name (/home/chris/repos/gists/reflecting_annotations/main.dart, line 22, col 18)
[warning] Undefined class '' (/home/chris/repos/gists/reflecting_annotations/main.dart, line 22, col 18)
1 error and 1 warning found.
I am unable to find any particular use for reflect(Foo). The Type that the instance mirror is reflecting seems to have no useful properties. I am unable to even access the Foo class from it. The only thing I can do is grab the actual class from the reflectee property so that I can then do useful work with the reflectClass() function:
main() {
  print(reflect(main));
  print(reflect(Foo));
  print(reflectClass(reflect(Foo).reflectee).metadata[0].reflectee);
}
Which produces:
ClosureMirror on 'Closure: () => dynamic from Function 'main': static.'
InstanceMirror on Type: class 'Foo'
[meta] Foo should not be used in real life
Ah, so perhaps that is the use case for reflecting on a class. When the class is not known as runtime (e.g. it is passed into a function), one could reflect on the supplied class, grab the reflectee property, and then use reflectClass(). Or is there some other use that I am missing?


Day #59

No comments:

Post a Comment