I've created a singleton class which I want to extend. It (half) works in that it only creates a single instance of the class, but properties added to the subclass are undefined. Here is the original singleton:
class Singleton
_instance = undefined
#getInstance: ->
if _instance is undefined
console.log 'no instance exists, so create one'
_instance = new _Singleton()
else
console.log 'an instance already exists.'
class _Singleton
constructor: ->
console.log 'new singelton'
module.exports = Singleton
And here is the subclass:
Singleton = require('./singleton')
class Stinky extends Singleton
constructor: ->
var1 : 'var1'
module.exports = Stinky
Now if I use the following in my node app:
Stinky = require './stinky'
thing1 = Stinky.getInstance()
thing2 = Stinky.getInstance()
console.log "Thing var1: #{thing1.var1}"
the getInstance() method behaves as expected, but var1 is undefined. If I do this same thing on non singleton classes they work fine. Thanks.
I trimmed your code down a bit. Here are the 2 remaining classes:
class Singleton
#_instance: null
#getInstance: ->
#_instance or= new #( arguments... )
class Stinky extends Singleton
constructor: ( #num ) ->
thing1 = Stinky.getInstance( 1 )
thing2 = Stinky.getInstance( 2 )
console.log( thing1.num, thing2.num )
I made the following changes:
Merged Singleton and _Singleton
Changed _instance to #_instance so that it would be attached to Singleton rather than its prototype
Added arguments splat in getInstance (in case arguments are needed)
Pointing getInstance() to extended object rather than Singleton
In this example, I used 2 different numbers to ensure that the 2nd constructor was never called.
I see how you're using the _Singleton class to try to simulate a private class, but unfortunately I don't think you can use it in this case.
Here is some code that works:
class Singleton
_instance = undefined
constructor: ->
console.log 'new singleton'
#getInstance: ->
if _instance is undefined
console.log 'no instance exists, so create one'
_instance = new #()
else
console.log 'an instance already exists.'
_instance
class Stinky extends Singleton
constructor: ->
console.log 'Stinky constructor'
#var1 = 'var1'
thing1 = Stinky.getInstance()
thing2 = Stinky.getInstance()
console.log "Thing var1: #{thing1.var1}", thing1, thing2
I removed the Node.js (require) code, but adding that in should be straightforward. The main difference is that the instance my code is creating is an instance of # or this. Doing so will make sure your constructor is called first then continue up the parent chain. Your code was explicitly creating an instance of _Singleton so your Stinky constructor was never being called. Another minor issue that you would have eventually noticed was that your getInstance method was not actually returning a instance of _instance.
I hope this helps,
Sandro
I'm not sure what the goal is, but you can achieve the same result by making Singleton a real singleton (a plain object):
Singleton =
doNothing: ->
# ...
doMoreNothing: ->
# ...
class Stinky
constructor: ->
#var1: 'var1'
getInstance: ->
return Singleton
It doesn't make much sense for Singleton to have a method that returns itself.
Related
How should I go about mapping a string to a class in Haxe, and then instantiating it?
class Foo{}
class Bar extends Foo{}
class Buzz extends Foo{}
// (...)
var classMap:Map<String, Class<Foo>> = [
"abc" => Bar,
"def" => Buzz
];
var myClass:Class<Foo> = classMap["abc"];
var myObj:Foo = new myClass(/* params */);
I thought this would work, but it throws unexpected ( after myClass. What's wrong?
Instead of storing Class<T> in the map and resorting to reflection for instantiation, it's a much nicer pattern to store references to the constructors (using their function type) as detailed in this haxe.org blog post.
class Foo {}
class Bar extends Foo {
public function new() {}
}
class Buzz extends Foo {
public function new() {}
}
var constructors:Map<String, Void->Foo> = [
"abc" => Bar.new,
"def" => Buzz.new
];
var construct:Void->Foo = constructors["abc"];
var myObj:Foo = construct();
https://try.haxe.org/#49E93
Unlike the Type.createInstance() approach, this doesn't allow you to pass arbitrary arguments to the constructors they might not even accept, so it's much more type-safe. It also automatically works with dead code elimination because Haxe sees that the constructors are referenced.
You should use Type.createInstance to create an instance of that class. new will only work if you want to directly call the constructor on the Class name itself new Foo()
I suggest you do it this way:
var myClass:Class<Foo> = classMap["abc"];
var myObj:Foo = Type.createInstance(myClass, [/* params */]);
Try it online here: https://try.haxe.org/#3134A
I am having a hard time understanding how to get the following code structure to work.
In Scala I have a class MyClass which inherits from SomeClass I added a var member variable in this case called mutableArray and it is being updated in the overridden method overridingSomeClassMethod and is called when I create a new instance of the MyClass a number of times right away. But in main when I try and get the updated mutableArray variable it prints out the instantiated var as if it is immutable or only has scope in the overriding method.
I can't change the method in parent SomeClass, and I tried creating a companion object as well as putting the variable in the encompassing SomeOtherObject but I get the same exact issue.
import scala.collection.mutable.ArrayBuffer
object SomeOtherObject{
case MyClass(...) extends SomeClass(..){
var mutableArray: ArrayBuffer[Int] = ArrayBuffer.fill(5)(0)
def overridingSomeClassMethod(...){
var someReturnVar = 0.0
mutableArray(0) += 1
println(mutableArray.mkString) // last output -> 84169
someReturnVar
}
}
def main(args: Array[String]){
var mc = new MyClass
println(mc.mutableArray.mkString) // output -> 00000
}
}
You can use an early initializer:
case MyClass(...) extends {
var mutableArray: ArrayBuffer[Int] = ArrayBuffer.fill(5)(0)
} with SomeClass(..) {
Probably you are hitting the infamous "one question FAQ" about initialization order.
If the method is invoked by the superclass constructor, then your initialization happens after that, resetting the data to zero.
As someone who worked more in Java, I am having a bit of difficulty wrapping my head around polymorphic references to class attributes in Python.
What I would like to do is have a method in the base class which modifies a "static" variable (aka class attribute) of the base class, but when calling the method from the derived class, for the method to modify the class attribute of the derived class, not the base class. Note, I am NOT overriding the method in the derived class.
For example, I have something like:
class BaseClass:
itemList = []
def addItem(thing):
BaseClass.itemList.append(thing)
class Child1(BaseClass):
pass
class Child2(BaseClass):
pass
...
Child1.addItem("foo")
Child2.addItem("bar")
print(str(Child1.itemList))
I'd like: "foo"
I get: "foo, bar"
Now, I understand that because of "BaseClass.itemList.append(thing)", it will reference the class attribute of the base class.
Put another way, is there a way to avoid saying "BaseClass.itemList", but keep it static, or do I need to instead override the method in each of the child classes?
You can have a "static" class variable that can be changed by every instance of the class:
class BaseClass:
itemList = []
def addItem(self, thing):
self.itemList.append(thing)
class Child1(BaseClass):
itemList = []
class Child2(BaseClass):
itemList = []
# each class has its own "itemList"
# now we can instantiate each class and use the different itemLists:
c1 = Child1()
c1.addItem("foo")
c2 = Child2()
c2.addItem("bar")
c3 = Child1()
c3.addItem("foo2")
print(str(Child1.itemList)) # prints: ['foo', 'foo2']
print(str(Child2.itemList)) # prints: ['bar']
I'm not sure if the title says it all.
What I'm trying to do is to have a super class (or a more or less abstract class) which then is used by another class which is extending itself from the super class.
Now what I did was to create a simple script:
class Animal
constructor: (#name, #sound) ->
setSound: (#sound) ->
sound: ->
alert "#{#sound}!!!"
name: ->
alert "#{#name}"
class Dog extends Animal
constructor: (#name) ->
#setSound "Woof"
doggy = new Dog "Max"
doggy.sound()
As you can see - this is just a crappy example but what happens is, when I now call doggy.sound() I get an TypeError in return.
You can see this script in action here: http://jsfiddle.net/zrVZb/1/
Am I doing something wrong or is this even a bug in coffeescript?
edit: I just saw, that it is contructor and not construct. But now I'm getting the TypeError instead.
Thanks
Your method is called sound. But then you pass an attribute with the same name, which overwrites this method. Try renaming your sound method into makeSound :
http://jsfiddle.net/V7Dx8/1/
I have two coffeescript classes something like this. In the base view model I have a method that I want to override in the child that inherits from the base view model.
class exports.BaseViewModel
constructor: () ->
someBaseMethod: =>
console.log "I'm doing the base stuff"
class ChildViewModel extends BaseViewModel
constructor: () ->
someBaseMethod: =>
#doSomethingFirst()
super #someBaseMethod()
This isn't working as is because the line super #someBaseMethod() calls itself creating an infinite loop.
Is it possible to achieve what I want here?
Yes, call super just like it was a function (it represents a reference to the superclass version of the method you're in):
class ChildViewModel extends BaseViewModel
constructor: ->
someBaseMethod: =>
#doSomethingFirst()
super()