I'd like to check if the object x implements (is instance of) the mixin MyInterface:
Ext.define('MyInterface', {
interfaceMethod: Ext.emptyFn
});
Ext.define('Foo', {
mixins: {
myInterface: 'MyInterface'
}
});
var x = new Foo();
doesn't work work:
console.log(x instanceof MyInterface);
ugly workaround:
var isInstanceOfMyInterface = false;
for (var i in x.mixins) {
if (x.mixins[i].$className == 'MyInterface') {
isInstanceOfMyInterface = true;
}
}
console.log(isInstanceOfMyInterface);
The workaround has one major issue: it doesn't work if a subclass of MyInterface is used.
jsfiddle
A pattern the Ext core uses is to apply a mixin specific property so you can test for its existence. It's a lot cheaper than an instanceof check as well. For example:
Ext.define('MyInterface', {
isMyInterface: true,
interfaceMethod: Ext.emptyFn,
});
Ext.define('Foo', {
mixins: {
myInterface: 'MyInterface'
}
});
var x = new Foo();
console.log(x.isMyInterface);
Mixins solve the problem of multiple inheritance because there is no way to make class C inherit from both A and B in plain JavaScript. The logic is then let class C to inherit from A and use class B as mixin. The mixin B is a sort of repository of additional methods and properties for C.
When the mixin B is used in class C, all its methods and properties are copied to the prototype of C and when C is instantiated it contains its own methods, methods of A, because it inherits from A, and B because mixin's methods are added to it.
Also, C can use more than one mixin to add additional methods/properties. Using mixin does not change the class name of the target class, C stays C.
Internally in Ext used mixins are held as object in mixins object of the target class as name/value pairs.
Summed together, your way is already the fine way to check if a class uses a mixin, nevetheless, it can be improved:
you can implement the above code as a method of the class(es) you want to check
you can break the above look once the mixin is found to save some cycles
Related
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.
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.
I want to have the following functionality in AngularJs as I have in C++ or Java(while I used GWT).
I have Class A with list of references to Class B's object and vica-versa so that I can say something like this. A's_object->B's_reference->show_B's_property
class A{
list<B*> B_ref;//points to B's class objects
......and more
}
class B{
list<A*> A_ref;//points to A's class objects
......and more
}
I mean is it even possible?Please Guide
AngularJs is a framework that uses html, css, and Javascript to easily create single-page applications. Your question would pertain to Javascript rather than the AngularJs framework.
The kind of behavior that you are looking for would be difficult to see in Javascript due to the nature of the language. Javascript is not a language that supports classes in the same way as C++ and Java. Javascript is a dynamic language that is functional based, rather than object oriented.
Javascript can support classes, but not in the same manner as you would be used to in languages like C++ and Java. Javascript instead uses prototypes. Basically, each object has an associated prototype (which is somewhat similar to the static behavior in C++ and Java classes) and this prototype can be decorated with methods and properties. New objects are cloned from existing objects, and the prototypes of the new objects inherits from the original prototype.
This allows many object-oriented features to be imitated in Javascript. I would recommend that you read up about the difference between Javascript and languages like C++.
http://en.wikipedia.org/wiki/Prototype-based_programming
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript
function A(color) {
this.bRef = [];
this.color = color;
// and more
}
function B(name) {
this.aRef = [];
this.name = name;
// and more
}
var a = new A();
var b1 = new B('foo');
var b2 = new B('bar');
a.bRef.push(b1);
a.bRef.push(b2);
var a1 = new A('red');
var a2 = new A('black');
b1.aRef.push(a1);
b1.aRef.push(a2);
console.log(a.bRef[1].name); // bar
console.log(a.bRef[0].aRef[0].color); // red
console.log(a.bRef[0].aRef[1].color); //black
b2.name = 'boo';
console.log(a.bRef[1].name); // boo
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.
I'm trying to follow along the excellent tutorial backbonerails produced by Brian Mann. Unfortunately (for me because I'm a noob) he's using coffeescript. What's confusing is my assumptions of the following code:
class App.Views.Users extends Backbone.View
I believed was the equivalent of:
Users = Backbone.View.extend({});
in plain javascript. However, when I place the coffeescript code in trycoffeescript I get:
var _ref,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
App.Views.Users = (function(_super) {
__extends(Users, _super);
function Users() {
_ref = Users.__super__.constructor.apply(this, arguments);
return _ref;
}
return Users;
})(Backbone.View);
My question is am I wrong in my assumption of what plain javascript should produce, am I incorrectly approaching the way to interpret the coffee script, or am I beyond hope?
Classes in coffeescript can't guarantee that the classes they're extending have an extend method, so it wouldn't be possible for the coffeescript to compile to Backbone.View.extend, without specifically requiring all the classes it's used with to provide the extend method.
However, if you look at the source of _.extend (which Backbone uses) you'll see that it's fairly similar to the __extends method that coffeescript generates and uses.
The coffeescript compiled version is obviously more verbose, but in practice I've never noticed a difference between class MyView extends Backbone.View and MyView = Backbone.View.extends({}}; so you can probably use whichever one you prefer.
EDIT: One possible difference is actually the super coffeescript keyword, which will only work if you're using coffeescript classes. However, you should still be able to replicate that functionality with .extends by calling the superclass function directly.