Skip to content

Instantly share code, notes, and snippets.

@arboleya
Created August 10, 2012 14:20
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save arboleya/3314539 to your computer and use it in GitHub Desktop.
Save arboleya/3314539 to your computer and use it in GitHub Desktop.
Private methods/properties in CoffeeScript.
# PRIVATE METHODS/PROPERTIES - COFFEESCRIPT
# ------------------------------------------------------------------------------
# Simple hack to protect private methods and properties from outside classes,
# all props and methods starting with '_' will be unaccessible from outside.
class AccessModifiers
@for:( scope )->
api = {}
for key, value of scope
# match everything that's private (starting with '_')
if key.match /^\_/m
# creates a general getter/setter to rise_error events
# for users trying to access private properties/methods.
(rise_error = ->
key = arguments.callee.key
msg = "Cannot access private property/method '#{key}'."
throw new Error msg).key = key
api.__defineGetter__ key, rise_error
api.__defineSetter__ key, rise_error
# match the public methods
else
# create getter/setter for properties and wrapper for methods
getter = -> scope[arguments.callee.key]
setter = (value)-> scope[arguments.callee.key] = value
wrapper = (params...) ->
scope[arguments.callee.key].apply scope, params
getter.key = setter.key = wrapper.key = key
# defines public methods
if typeof value == 'function'
api[key] = wrapper
# defines public properties
else
api.__defineGetter__ key, getter
api.__defineSetter__ key, setter
return api
# USAGE
# ------------------------------------------------------------------------------
# Simply put a 'return AccessModifiers.for @' in your class constructior.
#
# class MyClass extends MyAnotherClass
#
# constructor:->
# return AccessModifiers.for @
#
# public_prop: 1
# public_method:->
# console.log "i am pub"
#
# _private_prop: 1
# _private_prop:->
# console.log "i am pub"
# EXAMPLE
# ------------------------------------------------------------------------------
class Bird
_secrets: [1,2,3,4]
# public
altitude: null
constructor:->
return AccessModifiers.for @
# public
fly:->
console.log "Bird is flying at altitude=#{@altitude}...\n-----"
# private
_copulate:->
class Eagle extends Bird
# public
family: null
constructor:->
@family = "Accipitridae"
@altitude = "5"
return AccessModifiers.for @
# public
hunt:-> @_action @family
# private
_action:( family )->
console.log "Family #{family} needs to fly in order to hunt!"
@fly()
# TESTING
# ------------------------------------------------------------------------------
eagle = new Eagle()
# OK
eagle.hunt()
eagle.family = "OVERWRITED"
eagle.altitude = "OVERWRITED"
eagle.hunt()
# PRIVATE (will rise an error each)
try
eagle._action
catch err
console.log err
try
eagle._copulate
catch err
console.log err
try
eagle._secrets
catch err
console.log err
@arboleya
Copy link
Author

Output:

$ coffee public.coffee
Family Accipitridae needs to fly in order to hunt!
Bird is flying at altitude=5...
-----
Family OVERWRITED needs to fly in order to hunt!
Bird is flying at altitude=OVERWRITED...
-----
[Error: Cannot access private property/method '_action'.]
[Error: Cannot access private property/method '_copulate'.]
[Error: Cannot access private property/method '_secrets'.]

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