What is the best way to dynamically create classes in CoffeeScript so you can create objects from them later?
I found ways to do this, but I'm not sure if there is an even better (or simpler) way to achieve it. Please let me know your thoughts on my code.
Let's start with simple non-dynamic classes:
class Animal constructor: (@name) -> speak: -> alert "#{@name} says #{@sound}" class Cat extends Animal constructor: (@name) -> @sound = "meow!" garfield = new Cat "garfield" garfield.speak()
As expected, Garfield says meow!
But now we want to dynamically generate classes for more animals, which are defined as follows:
animalDefinitions = [ kind: 'Mouse' sound: 'eek!' , kind: 'Lion' sound: 'roar!' ]
The first naive attempt fails:
for animal in animalDefinitions animal.class = class extends Animal constructor: (@name) -> @sound = animal.sound mutant = new animalDefinitions[0].class "mutant" mutant.speak()
The animal we just created, mutant , must be a mouse. However, he says a roar! This is because animal.sound is evaluated only when instantiating the class. Fortunately, from JavaScript we know a proven way to solve this problem: closing:
for animal in animalDefinitions makeClass = (sound) -> class extends Animal constructor: (@name) -> @sound = sound animal.class = makeClass(animal.sound) mickey = new animalDefinitions[0].class "mickey" mickey.speak() simba = new animalDefinitions[1].class "simba" simba.speak()
Now it works as desired, mickey mouse says eek! and the simba lion speaks a roar! But this is already somewhat complicated. I am wondering if there is an easier way to achieve this result, perhaps by directly contacting the prototype. Or am I completely mistaken?