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:
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.