Skip to content

Instantly share code, notes, and snippets.

@robinsax
Last active March 7, 2018 01:40
Show Gist options
  • Save robinsax/beb8ff290e2f22282b6e14560d5f13f0 to your computer and use it in GitHub Desktop.
Save robinsax/beb8ff290e2f22282b6e14560d5f13f0 to your computer and use it in GitHub Desktop.
An implementation of callable objects in CoffeeScript
# Callable objects like jQuery's $ are cool but tricky to implement. Here's
# an example of a class "decorator" that makes classes callable.
#
# The limitation is it will break typeof and instanceof checks against the
# resulting object.
# A class decorator to make instances callable.
# Calling instances will invoke their _call() method.
callable = (Class) ->
() ->
# Create an instance.
inst = new Class
# Create a function that invokes _call()
func = () ->
inst._call.apply @, arguments
# Copy the properties of the instance onto the function.
obj = inst
while true
names = Object.getOwnPropertyNames obj
for name in names
Object.defineProperty func, name, Object.getOwnPropertyDescriptor obj, name
if not (obj = Object.getPrototypeOf obj)
break
# Return the function.
func
# An object we want to be callable.
Thing = callable class _Thing
constructor: () ->
console.log 'created'
@x = 200
_call: () ->
console.log 'foo', arguments
bar: () ->
console.log 'bar', @x
# Create an instance.
instance = new Thing
# Call the instance.
instance('Hello', 'world')
# Call an instance method.
instance.bar()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment