moonscript/moon/init.moon
2011-10-28 22:12:27 -07:00

95 lines
1.9 KiB
Plaintext

if not moon or not moon.inject
module "moon", package.seeall
util = require "moonscript.util"
export *
dump = util.dump
-- run a function with scope injected before its function environment
run_with_scope = (fn, scope, ...) ->
old_env = getfenv fn
env = setmetatable {}, {
__index: (name) =>
val = scope[name]
if val != nil
val
else
old_env[name]
}
setfenv fn, env
fn ...
-- wrap obj such that calls to methods do not need a reference to self
bind_methods = (obj) ->
setmetatable {}, {
__index: (name) =>
val = obj[name]
if val and type(val) == "function"
bound = (...) -> val obj, ...
self[name] = bound
bound
else
val
}
-- use a function to provide default values to table
-- optionally specify a starting table
-- fibanocci table:
-- t = defaultbl {[0]: 0, [1]: 1}, (i) -> self[i - 1] + self[i - 2]
defaultbl = (t, fn) ->
if not fn
fn = t
t = {}
setmetatable t, {
__index: (name) =>
val = fn self, name
rawset self, name, val
val
}
-- chain together tables by __index metatables
extend = (...) ->
tbls = {...}
return if #tbls < 2
for i = 1, #tbls - 1
a = tbls[i]
b = tbls[i + 1]
setmetatable a, __index: b
tbls[1]
-- shallow copy
copy = =>
t = {}
for key, val in pairs self
t[key] = val
t
-- mixin class properties into self, call new
mixin = (cls, ...) =>
meta = getmetatable cls
for key, val in pairs meta.__index
self[key] = val if not key\match"^__"
cls.__init self, ...
-- mixin methods from an object into self
mixin_object = (object, methods) =>
for name in *methods
self[name] = (parent, ...) ->
object[name](object, ...)
-- mixin table values into self
mixin_table = (tbl, keys) =>
if keys
for key in *keys
self[key] = tbl[key]
else
for key, val in pairs tbl
self[key] = val