Instantiating a class by String name in Dart - dart

I am trying to call a method of a class that I only know by name as a String. Now therefore I would need a ClassMirror of that class that allowes me to instantiate an instance. However, creating ClassMirrors seems to be only possible by entering a type using reflectClass(Type) or by passing an already existing instance of that class into reflect(dynamic). So these aren`t helping if I only have a String.
In Java you can do this pretty easily, by calling Class.forName(String). Then you would get a Constructor instance, make it accessibly and call it.
Does anyone know if this is even possible in dart? What seems weird is that once you have a ClassMirror you can access fields and methods by passing symbols, which can be created by Strings.

You can put a specific list of strings to map to a specific list of closures to create a new object with specific parameters.
But you can't get a reflection without using dart:mirrors, which is being deprecated, and also had a negative impact on tree shaking to get the payload size down.
In general, you're invited to look at the package:reflectable to achieve most of what you'd want out of dart:mirrors, using source-to-source builders.

Related

Using the analyzer package, is it possible to create an instance of a DartType representing a would-be generated code?

While using the analyzer package, I was wondering if it was possible to create an instance of its DartType object.
The issue I'm facing is, the analyzer output doesn't give me a valid DartType for a given class because that class has yet to exist (it is not yet generated by a code-generator).
I can work around not using DartType directly and instead make some copycat class. But that adds a lot of complexity. So I'd like to be able to create a DartType representing the would-be generated class.
I've looked into the TypeSytem/TypeProvider objects which seem to object type-related utilities but didn't find anything I wanted.
Is that possible?

Delphi Polymorphism using a "sibling" class type

We have an app that makes fairly extensive use of TIniFile. In the past we created our own descendant class, let's call it TMyIniFile, that overrides WriteString. We create one instance of this that the entire app uses. That instance is passed all around through properties and parameters, but the type of all of these is still TIniFile, since that is what it was originally. This seems to work, calling our overridden method through polymorphism, even though all the variable types are still TIniFile. This seems to be proper since we descend from TIniFile.
Now we are making some changes where we want to switch TMyIniFile to descend from TMemIniFile instead of TIniFile. Those are both descendants of TCustomIniFile. We'll also probably be overriding some more methods. I'm inclined to leave all the declarations as TIniFile even though technically our class is no longer a descendant of it, just to avoid having to change a lot of source files if I don't need to.
In every tutorial example of polymorphism, the variable is declared as the base class, and an instance is created of the descendant class and assigned to the variable of the base class. So I assume this is the "right" way to do it. What I'm looking at doing now will end up having the variables declared as, what I guess you'd call a "sibling" class, so this "seems wrong". Is this a bad thing to do? Am I asking for trouble, or does polymorphism actually allow for this sort of thing?
TIniFile and TMemIniFile are distinct classes that do not derive from each other, so you simply cannot create a TMemIniFile object and assign it to a TIniFile variable, and vice versa. The compiler won't let you do that. And using a type-cast to force it will be dangerous.
You will just have to update the rest of your code to change all of the TIniFile declarations to TCustomIniFile instead, which is the common ancestor for both classes. That is the "correct" thing to do.
The compiler is your friend - why would you lie to it by using the wrong type ... and if you do lie to it why would you expect it to know what you want it to do?
You should use a base class that you derive from, like TCustomIniFile. I would expect compile issues if you are trying to make assignments which are known at compile time to be wrong.
The different classes have different signatures so the compiler needs to know which class it is using to call the correct method or access the correct property. With virtual methods the different classes setup their own implementation of those methods so that the correct one is called - so using a pointer to a base type when you call the virtual method it calls that method in the derived type because it is in the class vtable.
So if the code does compile, it's very likely that the compiler will not be doing the right thing ...

Map TRttiProperty to a class definition equivalent

I'm wondering if its possible to reference a class definition directly for purpose of using it in conjunction to RTTI (map a property to TRttiProperty, etc).
E.g.
I would like to use TMyClass.MyProperty as a TRttiProperty, without having to resolve it via a name/ string, this will keep my code and compiler integrity intact, as string variables may be misspelled, etc.
Thanks
Assuming which you want do something like this
P:=TRttiProperty(TMyClass.MyProperty);
or write a function like so
function GetPropertyInfo(P: reference to property):TRttiProperty;
This is not possible, to do this possible you will require which delphi has support to property references. So the only current way to access (reference) an class property is using his name via an string.

Is it bad design to base control flow/conditionals around an object's class?

I'm currently working on a Rails project, and have found times where it's easiest to do
if object.class == Foo
...
else if object.class == Bar
...
else
...
I started doing this in views where I needed to display different objects in different ways, but have found myself using it in other places now, such as in functions that take objects as arguments. I'm not precisely sure why, but I feel like this is not good practice.
If it's not good practice, why so?
If it's totally fine, when are times that one might want to use this specifically?
Thanks!
Not sure why that works for you at all. When you need to test whether object is instance of class Foo you should use
object.is_a? Foo
But it's not a good practice in Ruby anyway. It'd much better to use polymorphism whenever it's possible. For example, if somewhere in the code you can have object of two different classes and you need to display them differently you can define display method in both classes. After that you can call object.display and object will be displayed using method defined in the corresponding class.
Advantage of that approach is that when you need to add support for the third class or a whole bunch of new classes all you'll need to do is define display method in every one of them. But nothing will change in places where you actually using this method.
It's better to express type specific behavior using subtyping.
Let the objects know how they are displays. Create a method Display() and pass all you need from outside as parameter. Let "Foo" know to display foo and "Bar" know how to display bar.
There are many articles on replacing conditionals with polymorphism.
It’s not a good idea for several reasons. One of them is duck typing – once you start explicitly checking for object class in the code, you can no longer simply pass an instance of a different class that conforms to a similar interface as the original object. This makes proxying, mocking and other common design tricks harder. (The point can be also generalized as breaking encapsulation. It can be argued that the object’s class is an implementation detail that you as a consumer should not be interested in. Broken encapsulation ≈ tight coupling ≈ pain.)
Another reason is extensibility. When you have a giant switch over the object type and want to add one more case, you have to alter the switch code. If this code is embedded in a library, for example, the library users can’t simply extend the library’s behaviour without altering the library code. Ideally all behaviour of an object should be a part of the object itself, so that you can add new behaviour just by adding more object types.
If you need to display different objects in a different way, can’t you simply make the drawing code a part of the object?

Regarding F# Object Oriented Programming

There's this dichotomy in the way we can create classes in f# which really bothers me. I can create classes using either an implicit format or an explicit one. But some of the features that I want are only available for use with the implicit format and some are only available for use with the explicit format.
For example:
I can't use let inline* (or let alone) inside an explicitly defined class.
The only way (that I know) to define immutable public fields (not properties*) inside an implicitly defined class is the val bla : bla syntax.
But there's a redundancy here. Since I'll end up with two copy of the same immutable data, one private, one public (because in the implicit mode the constructor parameters persist throughout the class existence)
(Not so relevant) The need to use attributes for method overloading and for field's defaults is rather off putting.
Is there anyway I can work around this?
*For performance reasons
EDIT: Turns out I'm wrong about both points (Thanks Ganesh Sittampalam & MichaelGG).
While I can't use let inline in both implicit & explicit class definition, I can use member inline just fine, which I assume does the same thing.
Apparently with the latest F# there's no longer any redundancy since any parameters not used in the class body are local to the constructor.
Will be gone in the next F# release.
This might not help, but you can make members inline. "member inline private" works fine.
For let inline, you can work around by moving it outside the class and explicitly passing any values you need from inside the scope of the class when calling it. Since it'll be inlined, there'll be no performance penalty for doing this.

Resources