How to turn a dart function name into a string?

Viewed 776

for testing purposes, I want to be able to dynamically turn a function name like getUserLocationByUserID(String userID){} into a string 'getUserLocationByUserID' so I can use it elseWhere

So When you have a list of functions and you wanna iterate in them I wish to be able to do something like this

import 'package:flutter/material.dart';

void function1() {}
void function2() {}
void function3() {}

List<Function> functionsList = [function1, function2, function3];

String magicalFunctionThatGetsAStringOutOfAFunctionName(Function function) {
  String functionNameAsAString = ''; // magical code here  <----------------------------------------------
  return functionNameAsAString;
}

class FunctionTester extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: ListView.builder(
        itemCount: functionsList.length,
        itemBuilder: (context, index) => GestureDetector(
          onTap: functionsList[index],
          child: Container(
            width: 300,
            height: 300,
            child: Text(
              magicalFunctionThatGetsAStringOutOfAFunctionName(functionsList[index]),
              maxLines: 1,
              style: TextStyle(
                fontSize: 10,
              ),
            ),
          ),
        ),
      ),
    );
  }
}

4 Answers

Give this a try:

  String magicalFunctionThatGetsAStringOutOfAFunctionName(Function function) {
    String functionNameAsAString = function.toString();
    int s = functionNameAsAString.indexOf('\'');
    int e = functionNameAsAString.lastIndexOf('\'');

    return functionNameAsAString.substring(s + 1, e);
  }

This solution might be a bit hacky but quite cheap compare to other options.

Note: This can be simplified, I wrote it this way to be easy to read :)

As a one-liner function:

String functionToString(Function fn) => fn.toString().split('\'')[1].trim();

void main() {
  print(functionToString(functionToString));
}

Console results:

functionToString

As a get extension on Function:

void main() {
  print(main.asString);
}

extension on Function {
  String get asString => this.toString().split('\'')[1].trim();
}

Console:

main

This is possible in Dart using mirrors, however mirrors are not available in Flutter or Web (and could be discontinued - see https://github.com/dart-lang/sdk/issues/44489).

import 'dart:mirrors';

void function1() {}
void function2() {}
void function3() {}

List<Function> functionsList = [function1, function2, function3];

void main() {
  for (final func in functionsList) {
    ClosureMirror mirror = reflect(func);
    final name = MirrorSystem.getName(mirror.function.simpleName);
    print(name);
  }
}

An alternative could be to use a map to store the function names with the function references, like:

void function1() {}
void function2() {}
void function3() {}

final functions = {
  'function1': function1,
  'function2': function2,
  'function3': function3,
};

void main() {
  for (final functionName in functions.keys) {
    final function = functions[functionName];
    print(functionName);
  }
}

Since mirrors aren't available in Flutter, I suggest you take a look at code gen libraries, where you can programmatically generate code based on your code.

Related