Last active
March 7, 2018 01:40
-
-
Save robinsax/beb8ff290e2f22282b6e14560d5f13f0 to your computer and use it in GitHub Desktop.
An implementation of callable objects in CoffeeScript
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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