Skip to content

Instantly share code, notes, and snippets.

@Ceasar
Created August 10, 2012 14:37
Show Gist options
  • Save Ceasar/3314695 to your computer and use it in GitHub Desktop.
Save Ceasar/3314695 to your computer and use it in GitHub Desktop.
Does decorating a class method that uses super break it?
class Animal
constructor: (@name) ->
move: (meters) ->
alert @name + " moved #{meters}m."
class Snake extends Animal
move: ->
alert "Slithering..."
super 5
class Horse extends Animal
move: ->
alert "Galloping..."
super 45
big = (cls) ->
old_move = cls::move
cls::move = ->
alert "Trips."
old_move.apply(@)
tom = new Horse "Tommy the Palomino"
big Horse
tom.move()
# Alerts Trips., Galloping..., Tommy the Palomino moved 45m.
@edubkendo
Copy link

Hmm, this doesn't actually work for me, as I noted on twitter:
actually, when I try this code it doesn't properly grab the @name. Ran it in browser, it alerts " moved 45 mph"…
changed alerts to "console.log" and ran in console, got "undefined moved 45mph"
if I make the original move a bound function, it gets name right but then "trips" doesnt run.

@aseemk
Copy link

aseemk commented Aug 10, 2012

Echo @edubkendo's comment in Chrome -- doesn't maintain name, and I wouldn't expect it to since you've lost the reference to this when you call old_move(). Shouldn't be it old_move.call @ or similar?

Binding the function isn't right, either, btw -- it'd bound to this at the time that the class is defined or big is called, which isn't what you want.

@Ceasar
Copy link
Author

Ceasar commented Aug 10, 2012

Oops. You're right! Just ran into the issue the code I was testing this for. Investigating...

@Ceasar
Copy link
Author

Ceasar commented Aug 10, 2012

Right, I missed an important piece of scope. I've updated the gist with the correct way to do this. (Note the difference on line 21.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment