0

I'm perfectly willing to play with this until I get it right, but was hoping someone might give me a hint. The parameter is declared in the docs (gen-dartdocs/dart-mirrors/ClassMirror/newInstance.html) as

InstanceMirror newInstance(Symbol constructorName,
                      List positionalArguments,
                      [Map<Symbol,dynamic> namedArguments]);

There is a nice writeup on the format of positionalArguments and namedArguments in the docs. However, it is just a little on the abstract side of my current tolerance level.

A decent discussion also exists at http://japhr.blogspot.com/2014/06/dart-factory-method-pattern.html But, alas, no examples of actually passing args into the method.

In my case, I would like to simply pass two args, "title" and "description" into an unnamed subclass constructor.

Here's my code so far:

file: item.dart

import 'dart:mirrors';

abstract class Item {

    String title;
    String description;

    factory Item(String type) {
      MirrorSystem libs = currentMirrorSystem();
      LibraryMirror lib = libs.findLibrary(new Symbol('app.models'));
      Map<Symbol, Mirror> classes = lib.declarations;
      // To do: handle exception if class not found
      ClassMirror cls = classes[new Symbol(type)];
      // TODO:
      //  verify each subclass has no-arg ctor
      //  determ how to pass args to ctor.
      InstanceMirror inst = cls.newInstance(new Symbol(''), []);
      return inst.reflectee;
    }

    // conflicts w/ Item factory
//  Item(this.title, this.description);
}

And here's the class that gets instantiated:

file: model.dart

library app.models;

import 'item.dart' show Item;

/// The barebones model for a codelab. Defines constants used for validation.
class Codelab implements Item {
   // ...
}

Finally, here is how the Item factory is called. ItemElement is the superclass of its own hierarchy, subclassed by CodelabElement:

file: item_element.dart:

import 'item.dart' show Item;

class ItemElement {
    Item item;
    final String itemType;

    ItemElement() {
      item = new Item(itemType);
    }
    // ...
}

And CodelabElement:

file: codelab_element.dart

import 'model.dart' show Codelab;
import 'item_element.dart' show ItemElement;

class CodelabElement extends ItemElement {

    final itemType = "Codelab";

    CodelabElement() : super() {}

    //...
}

And then:

file: main.dart

void main() {
    var element = new CodelabElement();
}

Currently, the new Codelab instance is returned from newInstance() (very cool), but it doesn't contain the inherited 'title' and 'description' attrs.

Maybe it has something to do with my being unclear on the usage of "extends" and "implements".

Tom Russell
  • 1,015
  • 2
  • 10
  • 29
  • What do you mean by "subclass constructor". Can you please add the declaration of the class with the constructor you want to invoke? – Günter Zöchbauer Nov 05 '15 at 09:50
  • I included a fairly complete example for anyone interested. Still wrapping my head around the concepts... – Tom Russell Nov 06 '15 at 05:50
  • I'm just not able to figure out what you want to accomplish. It looks like the problem is mostly not about reflection/mirrors but about object instantiation in general. I have no idea what role the classes `ItemElement` and `CodelabElement` are suposed to play. What string would you actually pass as `type` to `new Item()`? – Günter Zöchbauer Nov 06 '15 at 06:45
  • If you're familiar with the "Polymer and Dart Codelab" example at [https://github.com/dart-lang/polymer-and-dart-codelab] , you'll see that I just removed the Polymer stuff and moved the Codelab* classes' code into respective Item* classes. I'm going to post this question again but with another example. – Tom Russell Nov 06 '15 at 07:35

1 Answers1

1

This should work

cls.newInstance(new Symbol(''), ['a', 1] /*, 
    {#arg1Name: 'arg1Value', #arg2Name: 'arg2Value'}*/ );

and is like

new MyClass('a', 1, arg1Name: 'arg1Value' /*, arg2Name: 'arg2Value'*/); 

Just saw, Named arguments are not implemented.

You can try it in DartPad

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • I'm using WebStorm. Performing the above results in the following error: Unhandled exception: No constructor 'MyClass.' with matching arguments declared in class 'Codelab'. NoSuchMethodError: incorrect number of arguments passed to method named 'MyClass.' Receiver: Type: class 'MyClass' Tried calling: MyClass.("arg1", "arg2") – Tom Russell Nov 06 '15 at 05:53
  • Looks like Dart is trying to compose a call to a named constructor with the name missing, doesn't it? – Tom Russell Nov 06 '15 at 05:56
  • Your question is about an advanced topic like mirrors, but your problem seems to be understanding classes, constructors, and inheritance. Your question doesn't show what you try to accomplish. I don't even know where to start follow-up questions to figure out what the problem is. – Günter Zöchbauer Nov 12 '15 at 05:19
  • True enough. I'll try to come up with a better example. It may be helpful if you could shed some light just on the error message and why it contains that '.' in "MyClass.('arg1', 'arg2')". – Tom Russell Nov 12 '15 at 05:41
  • 1
    I don't think this `.` is relevant. Probably just an oversight when the string for the error message is constructed for named (with `.`) or unnamed (without) constructors. – Günter Zöchbauer Nov 12 '15 at 05:58
  • OK. I was just confused. I didn't have the MyClass constructor defined correctly. – Tom Russell Nov 13 '15 at 09:57
  • So you got it working? Glad to hear. Please either accept my answer (checkmark below the up/down-vote buttons) if it is the solution to your question, or add another answer yourself and accept it (when you're allowed after one day), so this question doesn't stay open as unanswered. Thanks. – Günter Zöchbauer Nov 13 '15 at 10:00
  • I got another, simpler, example to work and was going to wait until I had this one done so I could also revise the example above into a working state at the same time. But I can do that later if there are requests for it. – Tom Russell Nov 15 '15 at 06:50
  • I went ahead and posted my working example at http://stackoverflow.com/questions/33562085 (question marked as duplicate of this one). – Tom Russell Nov 15 '15 at 08:13