-
Notifications
You must be signed in to change notification settings - Fork 9
Metaclasses #4
Comments
/sub (Isn't there a better way to subscribe to issues in github by the way?) |
Thanks for the tip! |
@polux there's subscribe button over on the right. |
Can we discuss this proposal in one of the next DEP meetings? We have a customer that would love use this feature, if available. Thanks! |
Can they provide some details on what they want to use it for? |
cc @Hixie |
Note that the right place to provide feedback isn't on this issue. Either email core-dev@ or file issues on the proposal's repo. |
Should we just lock the issue? I've seen others be confused about all the different places one can leave a comment. |
Metaclasses are the main pain point I have in dealing with Dart in the context of developing extensible platforms, i.e. platforms where core features get extended post-hoc. In particular I miss:
For example: abstract class LayoutManager { ... }
void registerLayoutManager(Class<LayoutManager> manager, String name) { ... } ...where
For example: class Foo {
Foo() { print("constructor"); }
static String get name => 'my-name';
static void test() => print('foo');
}
void main() {
var X = Foo;
Foo f = new X(); // prints "constructor"
print(X.name); // prints "my-name"
}
// assume Foo from above exists
class Bar extends Foo {
@override static String get name => 'bar';
@override void test() { print('bar'); super.test(); }
}
void register(Class<Foo> x) {
print("going to register ${x.name}");
}
void main() {
Foo X = Bar;
X.test(); // prints "bar" then "foo";
register(X); // prints "going to register bar"
register(Foo); // prints "going to register my-name"
} Virtual static fields are great for storing data about the class, as above. Virtual static methods are really useful too, though, for the same reason that regular static methods are useful: it lets you do logic that applies to all instances, without having to know which exact class you're dealing with. For example, a class could define a method that verifies if some data is valid input to the class; you would then check this before calling the constructor. With metaclasses, you don't know exactly which class you have, but you still need to check the data. See the example below.
The above are all useful, but really virtual constructors are the most important: abstract class Element {
new(String input);
static String get tagName;
static bool isValid(String input);
// ...
}
class FooElement extends Element {
@override new(String input): super.new(input) { /*...*/ }
@override static String get tagName => 'foo';
@override static bool isValid(String input) => (input == 'true') || (input == 'false');
}
class BarElement extends Element {
// inherits Element's constructor
@override static String get tagName => 'bar';
@override static bool isValid(String input) => (input == 'one') || (input == 'two');
}
Map<String, Class<Element>> registrations = {};
registerElement(Class<Element> e) {
registrations[e.tagName] = e;
}
instantiateElement(String tagName, String input) {
var c = registrations[tagName](input);
if (c.isValid(input))
return new c(input);
return null;
}
void main() {
registerElement(FooElement);
registerElement(BarElement);
// ...
assert(instantiateElement('foo', 'true') is FooElement);
assert(instantiateElement('bar', 'one') is BarElement);
} |
The DEP process has been discontinued, so closing this issue. |
This is a proposal to endow Type objects with type-specific behavior, effectively creating a distinct metaclass for each class. This will make classes behave as first class runtime values.
Repository: https://github.com/gbracha/metaclasses
The text was updated successfully, but these errors were encountered: