symbols in dart are opaque, dynamic string name used in reflecting out metadata from a library. simply put, symbols are a way to store the relationship between a human readable string and a string that is optimized to be used by computers.
reflection is a mechanism to get metadata of a type at runtime like the number of methods in a class, the number of constructors it has or the number of parameters in a function. you can even invoke a method of the type which is loaded at runtime.
in dart reflection specific classes are available in the dart:mirrors package. this library works in both web applications and command line applications.
syntax
symbol obj = new symbol('name'); // expects a name of class or function or library to reflect
the name must be a valid public dart member name, public constructor name, or library name.
example
consider the following example. the code declares a class foo in a library foo_lib. the class defines the methods m1, m2, and m3.
foo.dart
library foo_lib; // libarary name can be a symbol class foo { // class name can be a symbol m1() { // method name can be a symbol print("inside m1"); } m2() { print("inside m2"); } m3() { print("inside m3"); } }
the following code loads foo.dart library and searches for foo class, with help of symbol type. since we are reflecting the metadata from the above library the code imports dart:mirrors library.
foosymbol.dart
import 'dart:core'; import 'dart:mirrors'; import 'foo.dart'; main() { symbol lib = new symbol("foo_lib"); //library name stored as symbol symbol clstosearch = new symbol("foo"); // class name stored as symbol if(checkif_classavailableinlibrary(lib, clstosearch)) // searches foo class in foo_lib library print("class found.."); } bool checkif_classavailableinlibrary(symbol libraryname, symbol classname) { mirrorsystem mirrorsystem = currentmirrorsystem(); librarymirror libmirror = mirrorsystem.findlibrary(libraryname); if (libmirror != null) { print("found library"); print("checkng...class details.."); print("no of classes found is : ${libmirror.declarations.length}"); libmirror.declarations.foreach((s, d) => print(s)); if (libmirror.declarations.containskey(classname)) return true; return false; } }
note that the line libmirror.declarations.foreach((s, d) => print(s)); will iterate across every declaration in the library at runtime and prints the declarations as type of symbol.
this code should produce the following output −
found library checkng...class details.. no of classes found is : 1 symbol("foo") // class name displayed as symbol class found.
example: display the number of instance methods of a class
let us now consider displaying the number of instance methods in a class. the predefined class classmirror helps us to achieve the same.
import 'dart:core'; import 'dart:mirrors'; import 'foo.dart'; main() { symbol lib = new symbol("foo_lib"); symbol clstosearch = new symbol("foo"); reflect_instancemethods(lib, clstosearch); } void reflect_instancemethods(symbol libraryname, symbol classname) { mirrorsystem mirrorsystem = currentmirrorsystem(); librarymirror libmirror = mirrorsystem.findlibrary(libraryname); if (libmirror != null) { print("found library"); print("checkng...class details.."); print("no of classes found is : ${libmirror.declarations.length}"); libmirror.declarations.foreach((s, d) => print(s)); if (libmirror.declarations.containskey(classname)) print("found class"); classmirror classmirror = libmirror.declarations[classname]; print("no of instance methods found is ${classmirror.instancemembers.length}"); classmirror.instancemembers.foreach((s, v) => print(s)); } }
this code should produce the following output −
found library checkng...class details.. no of classes found is : 1 symbol("foo") found class no of instance methods found is 8 symbol("==") symbol("hashcode") symbol("tostring") symbol("nosuchmethod") symbol("runtimetype") symbol("m1") symbol("m2") symbol("m3")
convert symbol to string
you can convert the name of a type like class or library stored in a symbol back to string using mirrorsystem class. the following code shows how you can convert a symbol to a string.
import 'dart:mirrors'; void main(){ symbol lib = new symbol("foo_lib"); string name_of_lib = mirrorsystem.getname(lib); print(lib); print(name_of_lib); }
it should produce the following output −
symbol("foo_lib") foo_lib