In this tutorial you will learn about the Dart Symbol and its application with practical example.
Dart Symbol
Dart Symbol object used to refer an operator or identifier declared in a Dart program. Dart symbol are commonly used in APIs that refer to identifiers by name, because an identifier name can changes but not identifier symbols.
Dart symbols are opaque, dynamic string name used in reflecting out metadata from a library. Symbols is basically means to save the relationship between a human readable string and a string that is optimized to be used by computers.
Reflection is a mechanism that used to get metadata of a type at run-time for example – the number of methods in a class, the number of constructors it has or the number of parameters in a function.
In Dart, all of the reflection related classes are available in the dart:mirrors package. This library can be used with web applications as well as command line applications.
Syntax:-
Symbol for an identifier can be created using a hash (#) followed by the identifier name.
1 |
Symbol obj = new Symbol("name"); |
Here, the name must be a valid class, function, public member name, public constructor name, or library name.
Example:-
Lets create a file Foo.dart and put the following code in it –
Foo.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
library foo_lib; // libarary name can be a symbol // class name can be a symbol class Foo { // method name can be a symbol m1() { print("Inside m1"); } m2() { print("Inside m2"); } m3() { print("Inside m3"); } } |
Here, we have declared a class Foo in a library foo_lib, and defined three methods m1, m2, and m3 in class Foo.
Now, create another dart file FooSymbol.dart and put the following code in it –
FooSymbol.dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
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; } } |
In the above code we are loading Foo.dart library along with the dart:mirrors library because we will be reflecting the metadata from the above library. In the above code we are basically searching for the Foo class in foo_lib using Symbol.
The following line of code iterate through every declaration in the library at runtime and prints the declarations as type of Symbol.
1 |
libMirror.declarations.forEach((s, d) => print(s)); |
When we run the above Dart Program, we will see the following output –
Output:-
1 2 3 4 5 |
Found Library checkng...class details.. No of classes found is : 1 Symbol("Foo") // class name displayed as symbol class found. |
Display Number of Instance Methods In a Class
Example:-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
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)); } } |
Output:-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
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") |
Dart Convert Symbol to String
The MirrorSystem class available in dart:mirrors library allow us to convert a Symbol back to string.
Example:-
1 2 3 4 5 6 7 |
import 'dart:mirrors'; void main(){ Symbol lib = new Symbol("foo_lib"); String name_of_lib = MirrorSystem.getName(lib); print(lib); print(name_of_lib); } |
Output:-
1 2 |
Symbol("foo_lib") foo_lib |