Is it possible to execute static code using Dart? - static

Both Java and Javascript allow for a different way of executing static code. Java allows you to have static code in the body of a class while JS allows you to execute static code outside class definitions. Examples:
Java:
public class MyClass {
private static Map<String,String> someMap = new HashMap<String,String();
static {
someMap.put("key1","value");
someMap.put("key2","value");
SomeOtherClass.someOtherStaticMethod();
System.out.println(someMap);
}
}
JS (basically any JS code outside a class):
var myint = 5;
callSomeMethod();
$(document).ready(function () {
$("#hiddenelement").hide();
});
However, it seems like Dart supports either of both ways. Declaring global variables and methods is supported, but calling methods and executing code like in JS is not. This can only be done in a main() method. Also, static code inside a class is not allowed either.
I know Dart has other ways to statically fill a Map like my first example, but there is another case that I can think of for which this is required.
Let's consider the following CarRegistry implementation that allows you to map strings of the car model to an instance of the corresponding class. F.e. when you get the car models from JSON data:
class CarRegistry {
static Map<String, Function> _factoryMethods = new HashMap<String, Function>();
static void registerFactory(String key, Car factory()) {
_factoryMethods[key] = factory;
}
static Car createInstance(String key) {
Function factory = _factoryMethods[key];
if(factory != null) {
return factory();
}
throw new Exception("Key not found: $key");
}
}
class TeslaModelS extends Car {
}
class TeslaModelX extends Car {
}
In order to be able to call CarRegistry.createInstance("teslamodelx");, the class must first be registered. In Java this could be done by adding the following line to each Car class: static { CarRegistry.registerFactory("teslamodelx" , () => new TeslaModelX()); }. What you don't want is to hard-code all cars into the registry, because it will lose it's function as a registry, and it increases coupling. You want to be able to add a new car by only adding one new file. In JS you could call the CarRegistry.registerFactory("teslamodelx" , () => new TeslaModelX()); line outside the class construct.
How could a similar thing be done in Dart?
Even if you would allow to edit multiple files to add a new car, it would not be possible if you are writing a library without a main() method. The only option then is to fill the map on the first call of the Registry.createInstance() method, but it's no longer a registry then, just a class containing a hard-coded list of cars.
EDIT: A small addition to the last statement I made here: filling this kind of registry in the createInstance() method is only an option if the registry resided in my own library. If, f.e. I want to register my own classes to a registry provided by a different library that I imported, that's no longer an option.

Why all the fuss about static?
You can create a getter that checks if the initialization was already done (_factoryMethods != null) if not do it and return the map.
As far a I understand it, this is all about at what time this code should be executed.
The approach I showed above is lazy initialization.
I think this is usually the preferred way I guess.
If you want to do initialization when the library is loaded
I don't know another way as calling an init() method of the library from main() and add initialization code this libraries init() method.
Here is a discussion about this topic executing code at library initialization time

I encountered the same issue when trying to drive a similarly themed library.
My initial attempt explored using dart:mirrors to iterate over classes in a library and determine if they were tagged by an annotation like this (using your own code as part of the example):
#car('telsamodelx')
class TelsaModelX extends Car {
}
If so, they got automatically populated into the registry. Performance wasn't great, though, and I wasn't sure if how it was going to scale.
I ended up taking a more cumbersome approach:
// Inside of CarRegistry.dart
class CarRegister {
static bool _registeredAll = false;
static Car create() {
if (!_registeredAll) { _registerAll()); }
/* ... */
}
}
// Inside of the same library, telsa_model_x.dart
class TelsaModelX extends Car {}
// Inside of the same library, global namespace:
// This method registers all "default" vehicles in the vehicle registery.
_registerAll() {
register('telsamodelx', () => new TelsaModelX());
}
// Inside of the same library, global namespace:
register(carName, carFxn) { /* ... */ }
Outside of the library, consumers had to call register(); somewhere to register their vehicle.
It is unnecessary duplication, and unfortunately separates the registration from the class in a way that makes it hard to track, but it's either cumbersome code or a performance hit by using dart:mirrors.
YMMV, but as the number of register-able items grow, I'm starting to look towards the dart:mirrors approach again.

Related

Lazy initialisation of individual array elements

In Swift, lazy properties allow us to only initialise a class member when we ask for it instead of directly at runtime - useful for computationally expensive operations.
I have a class in Swift 4 that is responsible for initialising a strategy from an array of compile-time (developer-hardcoded) provided StrategyProtocol objects. It looks something like this:
class StrategyFactory {
private var availableStrategies: [StrategyProtocol] = [
OneClassThatImplementsStrategyProtocol(),
AnotherThatImplementsStrategyProtocol() // etc
]
public func createStrategy(): StrategyProtocol {
// Depending on some runtime-calculated operation
// How do I do this nicely here?
}
}
However, from my understanding, placing () at the end of each strategy initialises the objects(?), when I may only want to create one depending on certain runtime conditions.
Either way, is it possible to place lazy somewhere around the values in an Array class member to only instantiate the one I want when I ask for it? Or would I have to go about this with closures or some other alternative?
Current attempt
Is this doing what I think it is? Until I get the first element of the array and execute it, it won't actually instantiate the strategy?
private var availableStrategies: [() -> (StrategyProtocol)] = [
{ OneClassThatImplementsStrategyProtocol() }
]
Your "Current attempt" does what you think it does. You have an array
of closures, and the strategy is initialized only when the closure is
executed.
A possible alternative: Store an array of types instead of
instances or closures (as Zalman Stern also suggested).
In order to create instances on demand, a
init() requirement has to be added to the protocol (which must then
be satisfied by a required init() unless the class is final,
compare Why use required Initializers in Swift classes?).
A possible advantage is that you can query static properties
in order to find a suitable strategy.
Here is a small self-contained example, where createStrategy()
creates and returns the first "fantastic" strategy:
protocol StrategyProtocol {
init()
static var isFantastic: Bool { get }
}
class OneClassThatImplementsStrategyProtocol : StrategyProtocol {
required init() { }
static var isFantastic: Bool { return false }
}
final class AnotherThatImplementsStrategyProtocol : StrategyProtocol {
init() { }
static var isFantastic: Bool { return true }
}
class StrategyFactory {
private var availableStrategies: [StrategyProtocol.Type] = [
OneClassThatImplementsStrategyProtocol.self,
AnotherThatImplementsStrategyProtocol.self // etc
]
public func createStrategy() -> StrategyProtocol? {
for strategy in availableStrategies {
if strategy.isFantastic {
return strategy.init()
}
}
return nil
}
}
ANYCLASS, META TYPE AND .SELF may answer your question. (I am not expert on Swift, but use of metaclasses is likely what you want and Swift, as I expected, appears to support them.) You can look through this Stack Overflow search.
EDIT: In case it wasn't clear, the idea is to have the array of strategies contain the metaclasses for the protocols rather than instantiations. Though this depends on whether you want a new strategy object for each instantiation of the class with the lazy property or whether strategies are effectively global and cached ones created. If the latter, then the lazy array approach for holding them might work better.

PHPDoc: append methods to the current class, as if it were extending a class [duplicate]

Is there a way to document that a certain class has magic methods for every method defined in another class?
I am using PhpStorm, so I would be happy with any solution that will get autocomplete to work properly for that.
class A
{
// a bunch of functions go here...
}
/**
* Class B
* What should go here to make it work???
*/
class B
{
private $aInstance;
public function __construct() {
$this->aInstance = new A();
}
public function __call($name, $arguments) {
// TODO: Implement __call() method.
if(method_exists($this->aInstance, $name)) {
return $this->aInstance->{$name}(...$arguments);
}
throw new BadMethodCallException();
}
// a bunch more functions go here...
}
The proper solution is to use supported #method PHPDoc tags. This way it will also work in other editors/IDEs that support PHPDoc and understand such standard tag.
This approach requires every method to be listed separately. More on this in another StackOverflow question/answer: https://stackoverflow.com/a/15634488/783119.
In current PhpStorm versions you may use not-in-PHPDoc-specs (and therefore possibly PhpStorm-specific) #mixin tag.
Adding #mixing className in PHPDoc comment for your target class should do the job for you.
/**
* Class B
*
* #mixin A
*/
class B
{
Basically, #mixin tag does what actual PHP's traits do.
Please note that there is no guarantee that support for such tag will not be removed at some point in the future, although it's pretty unlikely.

Static and Normal class combined in one class

I am trying my best to explain the situation. I hope, what I wrote, is understandable.
We already have class defined like
public ref class TestClass
{
public:
TestClass();
virtual ~TestClass();
protected:
Car* m_car;
}
TestClass is managed C++ and Car is unmanaged C++.
So far so good, but now I need to make static object of TestClass also. So I modify the code like below
public ref class TestClass
{
private:
static TestClass^ s_test = nullptr ;
public:
TestClass();
virtual ~TestClass();
static TestClass^ Instance();
protected:
Car* m_car;
}
When I want to use static instant of the class, I just get it from calling
TestClass staticobj = TestClass::Instance();
Elsewhere, just call
TestClass normalobj = gcnew TestClass();
Instance function is creating s_test static object and returns it.
TestClass ^ TestClass::Instance()
{
if(s_test == nullptr)
{
s_test = gcnew TestClass();
s_test->m_car = new Car();
}
return s_test;
}
Is it a good approach?
Is there any other better approach to accomplish same thing?
Edit :
FYI Above code works.
I combined Krizz and Reed Copsey’s solutions. That solve independent Singleton and memory leak.
Here is my sample code,
Special Singleton class derived from test class,
public ref class SpecialSingletonTestClass: public TestClass
{
private:
static SpecialSingletonTestClass ^ s_ SpecialSingletonTestClass = nullptr;
public:
SpecialSingletonTestClass ();
static SpecialSingletonTestClass ^ Instance();
};
Changed the testclass so it has now one more finalizer function.
public ref class TestClass
{
public:
TestClass ();
virtual ~ TestClass ();
! TestClass ();
protected:
Car* m_car;
}
I tested above pattern , it worked.
Thanks you guys,
L.E.
Is it a good approach?
I would probably not consider this a good approach, as you're making a single class both a singleton and a normal class that you can instance directly.
Typically, if you need a singleton, this would preclude the need or desire to be able to instantiate the class.
If you truly need to have a way to have a "global" instance of this class, I would encapsulate that in a separate class which implements the singleton. This would, at least, make it clear that you are dealing with something that's a single instance in that case. I would not mix both use cases into a single class.
Well, actually there is an issue with memory leaks in your code.
You declare only virtual ~TestClass(); which, for managed classes, are internally turned by C++/CLI compiler into implementation of IDisposable.Dispose().
Therefore, if you put delete car into it, it will be called only if you delete test_class or, e.g. wrap into using (TestClass tst) {} block when using from C#.
It will not be called when object is GCed!
To be sure it is called you need to add finalizer to your class !MyClass(); which is turned by compiler into virtual void Finalize() and thus non-deterministically called when GC is freeing an object.
And it is the only way to free m_car of singleton object.
Therefore, I suggest:
TestClass()
{
m_car = new Car();
}
~TestClass()
{
if (m_car)
delete m_car;
m_car = NULL;
}
!TestClass()
{
if (m_car)
delete m_car;
m_car = NULL;
}
I'm unsure as to what situation you could possibly be in that would require both singleton-style semantics and normal creation semantics for the same class.
As far as what you've coded though, it looks completely fine. My only comments would be that your Instance() function shouldn't need to perform construction on Car, the Instance() function should just call the default constructor of TestClass which should do all that.
EDIT
In reference to:
#crush . The class is already define i just need to get static object of it. Singleton means only one object of the class, but in this case, class have multiple normal object. But i want to use only one object of this class for one specific goal only for limited period of time. – L.E. 2 mins ago
A singleton is (usually) a sign of bad design - alot of people call it an anti-pattern actually. Chances are if you just need this one single specific instance of this class for a limited period of time there are some issues:
Singleton design is made for static-style existence - the variable will live for the scope of your program after lazily initialized.
Allowing global access will move your code towards spaghetti logic. You'd be better off dynamically allocating the one you need and passing the pointer to it to where you need it to be. A shared_ptr would be good for this.
You should find a way around the singleton-style implementation in this case even if it's more work for you - it'll almost certainly be better design.

Importing a class with a specific parameter

I got a ViewModel which I export with MEF. I'd like this ViewModel to be initialized differently each time it's being imported, according to an enum/specific object parameter that will be provided to it.
I've been reading a little on the subject and I found that maybe this -
http://msdn.microsoft.com/en-us/library/ee155691.aspx#metadata_and_metadata_views
would be able to fit my needs, but I'm not sure that this would be the best way to do it.
Another method I've been thinking about is importing the class normally, and then once I've an instance, to call a special initialization method that would receive my parameter. However this doesn't seem like a classic MEF implementation, and maybe losses some of its "magic".
I'm hoping someone would be able to point out for me what would be the recommended method to achieve this.
Thanks!
A workaround is exporting a factory that creates instances of your type. While this means you cannot directly import thos instances, it does have the benefit that the logic to create them is the responsability of the factory so users of the class do not have to know about it:
public class ServiceWithParameter
{
public ServiceWithParameter( int a )
{
this.a = a;
}
private readonly int a;
}
[Export]
public class ServiceWithParameterFactory
{
public ServiceWithParameterFactory()
{
instance = 0;
}
public ServiceWithParameter Instance()
{
return new ServiceWithParameter( instance++ );
}
private int instance;
}
//now everywhere you need ServiceWithParameter:
[Import]
ServiceWithParameterFactory serviceFactory;
var instanceA = serviceFactory.Instance(); //instanceA.a = 0
var instanceB = serviceFactory.Instance(); //instanceB.a = 1
A more extensible way is telling the container you have a factory and an example is presented here: http://pwlodek.blogspot.com/2010/10/mef-object-factories-using-export.html

Creating New Array with Class Object in GWT

I would like to create a new array with a given type from a class object in GWT.
What I mean is I would like to emulate the functionality of
java.lang.reflect.Array.newInstance(Class<?> componentClass, int size)
The reason I need this to occur is that I have a library which occasionally needs to do the following:
Class<?> cls = array.getClass();
Class<?> cmp = cls.getComponentType();
This works if I pass it an array class normally, but I can't dynamically create a new array from some arbitrary component type.
I am well aware of GWT's lack of reflection; I understand this. However, this seems feasible even given GWT's limited reflection. The reason I believe this is that in the implementation, there exists an inaccessible static method for creating a class object for an array.
Similarly, I understand the array methods to just be type-safe wrappers around JavaScript arrays, and so should be easily hackable, even if JSNI is required.
In reality, the more important thing would be getting the class object, I can work around not being able to make new arrays.
If you are cool with creating a seed array of the correct type, you can use jsni along with some knowledge of super-super-source to create arrays WITHOUT copying through ArrayList (I avoid java.util overhead like the plague):
public static native <T> T[] newArray(T[] seed, int length)
/*-{
return #com.google.gwt.lang.Array::createFrom([Ljava/lang/Object;I)(seed, length);
}-*/;
Where seed is a zero-length array of the correct type you want, and length is the length you want (although, in production mode, arrays don't really have upper bounds, it makes the [].length field work correctly).
The com.google.gwt.lang package is a set of core utilities used in the compiler for base emulation, and can be found in gwt-dev!com/google/gwt/dev/jjs/intrinsic/com/google/gwt/lang.
You can only use these classes through jsni calls, and only in production gwt code (use if GWT.isProdMode()). In general, if you only access the com.google.gwt.lang classes in super-source code, you are guaranteed to never leak references to classes that only exist in compiled javascript.
if (GWT.isProdMode()){
return newArray(seed, length);
}else{
return Array.newInstance(seed.getComponentType(), length);
}
Note, you'll probably need to super-source the java.lang.reflect.Array class to avoid gwt compiler error, which suggests you'll want to put your native helper method there. However, I can't help you more than this, as it would overstep the bounds of my work contract.
The way that I did a similar thing was to pass an empty, 0 length array to the constructor of the object that will want to create the array from.
public class Foo extends Bar<Baz> {
public Foo()
{
super(new Baz[0]);
}
...
}
Baz:
public abstract class Baz<T>
{
private T[] emptyArray;
public Baz(T[] emptyArray)
{
this.emptyArray = emptyArray;
}
...
}
In this case the Bar class can't directly create new T[10], but we can do this:
ArrayList<T> al = new ArrayList<T>();
// add the items you want etc
T[] theArray = al.toArray(emptyArray);
And you get your array in a typesafe way (otherwise in your call super(new Baz[0]); will cause a compiler error).
I had to do something similar, I found it was possible using the Guava library's ObjectArrays class. Instead of the class object it requires a reference to an existing array.
T[] newArray = ObjectArrays.newArray(oldArray, oldArray.length);
For implementing an array concatenation method, I also stepped into the issue of missing Array.newInstance-method.
It's still not implemented, but if you have an existing array you can use
Arrays.copyOf(T[] original, int newLength)
instead.

Resources