local function create(cat, v1, v2)
local meta = { __concat = cat }
return setmetatable({v1}, meta), setmetatable({v2}, meta)
end
do local a, b, c = "foo", "bar", "baz"
assert(a..b == "foobar")
assert(a..b..c == "foobarbaz")
end
do local a, b = create(function(a, b) return a end)
assert(a..b == a)
assert(b..a == b)
assert(a..b..b == a)
assert(a..a..b == a)
assert(a..b..a == a)
assert(a..b..b..b..b..b..b..b == a)
end
do local a, b = create(function(a, b) return b end)
assert(a..b == b)
assert(b..a == a)
assert(a..b..b == b)
assert(a..a..b == b)
assert(b..b..a == a)
assert(a..a..a..a..a..a..a..b == b)
end
do local a, b = create(function(a, b)
return (type(a) == "string" and a or a[1])..
(type(b) == "string" and b or b[1])
end, "a", "b")
assert(a..b == "ab")
assert(a..b == "ab")
assert(a..b..b == "abb")
assert(a..b..a == "aba")
assert(a..a..a..a..a..a..a..b == "aaaaaaab")
assert(a..a..a.."x".."x"..a..a..b == "aaaxxaab")
assert("x"..a..a..a..a..a..a..b == "xaaaaaab")
assert(a..b..a..b..a.."x".."x".."x" == "ababaxxx")
end
do local a, b = create(function(a, b)
if a ~= b then local x = gg end
return (type(a) == "string" and a or a[1])..
(type(b) == "string" and b or b[1])
end, "a", "b")
local y
for i=1,100 do y = a..b end
assert(y == "ab")
for i=1,100 do y = a..b.."x" end
assert(y == "abx")
for i=1,100 do y = a..b.. 1 .. "z" end
assert(y == "ab1z")
end