lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Mon, Apr 6, 2009 at 6:29 PM, Peter Cawley <lua@corsix.org> wrote:
> It seems that placeholder _N can only be used if there are at least N
> placeholders.

Indeed, that's the problem, blame it on over-hasty reading of the documentation.

Here is take 2, passes all tests so far:

-- testbind.lua
-- Lua implementation of boost::bind
-- http://www.boost.org/doc/libs/1_38_0/libs/bind/bind.html
-- Thanks to Thomas Harning, jr and Peter Cawley.
local append = table.insert
local concat = table.concat
local max = math.max

_1,_2,_3,_4,_5 = {'_1'},{'_2'},{'_3'},{'_4'},{'_5'}
local placeholders = {[_1]=1,[_2]=2,[_3]=3,[_4]=4,[_5]=5}

function bbind(fn,...)
    local n = select('#',...)
    local args = {...}
    local holders,parms,bvalues,values = {},{},{'fn'},{}
    local nv,maxplace = 1,0
    for i = 1,n do
        local a = args[i]
        local place = placeholders[a]
        if place then
            append(holders,a[1])
            maxplace = max(maxplace,place)
        else
            local v = '_v'..nv
            append(bvalues,v)
            append(holders,v)
            append(values,a)
            nv = nv + 1
        end
    end
    for np = 1,maxplace do
        append(parms,'_'..np)
    end
    bvalues = concat(bvalues,',')
    parms = concat(parms,',')
    holders = concat(holders,',')
    local fstr = ([[
return function (%s)
    return function(%s) return fn(%s) end
end
]]):format(bvalues,parms,holders)
    --print(fstr)
    local res,err = loadstring(fstr)
    res = res()
    return res(fn,unpack(values))
end

bbind (print,_1,_2,true) (1,2)
-- 1	2	true
bbind (print,_2,_1,false) (1,2)
-- 2	1	false
bbind (print,_2,_1) (1,2)
-- 2	1
bbind (print,10,_1,20) (1)
-- 10	1	20
bbind (print,nil) ()
-- nil
bbind (print,nil,_1) (1)
-- nil 1
bbind (print,_3,_3) (10,20,30)
-- 30 30