Skip to content

Instantly share code, notes, and snippets.

@yloiseau
Last active August 29, 2015 14:05
Show Gist options
  • Save yloiseau/6bbb36c57d141341f380 to your computer and use it in GitHub Desktop.
Save yloiseau/6bbb36c57d141341f380 to your computer and use it in GitHub Desktop.

more functional, generic and dsl-ish version of https://gist.github.com/k33g/1dfb5bf477b7e121422d ;D

module prepostdeco

import java.lang.Math

# Decorator: apply checkers to parameters and result
function checkThat = |preTests...| {
    return |postTest| {
        return |fun| {
            return |args...| {
                _apply_tests_(preTests, args)
                let result = fun: invokeWithArguments(args)
                postTest(result)
                return result
            }
        }
    }
}

function _apply_tests_ = |tests, args| {
    for ( var i = 0, i < min(tests: length(), args: length()), i = i + 1) {
        tests: get(i)(args: get(i))
    }
}

function any = |v| -> v

function checkType = |t| {
    return |v| {
        require(v oftype t, v + " is not a " + t: getName())
        return v
    }
}

function greaterThan = |m| {
    return |v| {
        require(v > m, v + " is not greater than " + m)
        return v
    }
}

function lengthIs = |l| {
    return |v| {
        require(v: length() == l, "length of " + v + " is not " + l)
        return v
    }
}


let isInteger = checkType(Integer.class)
let isString = checkType(String.class)
let isPositive = greaterThan(0)

@checkThat(isInteger: andThen(isPositive), isString)(isString: andThen(lengthIs(2)))
function foo = |a, b| {
    return b + a
}


function main = |args| {
    try { println(foo(1, "b")) } catch (e) { println(e) }
    try { println(foo(-1, "b")) } catch (e) { println(e) }
    try { println(foo("a", 2)) } catch (e) { println(e) }
    try { println(foo(1, 2)) } catch (e) { println(e) }
    try { println(foo(10, "ab")) } catch (e) { println(e) }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment