lua-users home
lua-l archive

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


I came up with a little pure-Lua solution, maybe someone will find it useful!

----
cat = function(str)
  local insert = table.insert
  local concat = table.concat

  local parts = {str}
  return setmetatable({}, {
    __tostring = function()
      return concat(parts)
    end,
    __call = function(tbl, str)
      insert(parts, str)
      return tbl
    end,
  })
end
----

Example: print(cat "foo" "bar" "baz")
Output: foobarbaz

You do need to keep in mind that it's a table, not a string. You can
get a string back immediately just by calling tostring() on it though,
and it shouldn't be hard to improve this a bit. If you want to get a
string right after you're done, you could modify __call to return the
string if 'str' is nil. Then you'd use it like this:

cat "foo" "bar" "baz" ""
or
cat "foo" "bar" "baz" ()

~Jonathan

On Mon, Apr 5, 2010 at 3:13 AM, Duncan Cross <duncan.cross@gmail.com> wrote:
> On Mon, Apr 5, 2010 at 10:38 AM, Alexander Gladysh <agladysh@gmail.com> wrote:
>>>> Just to show one use case, I use a module system where you start each
>>>> module with:
>>
>>>> require 'dokidoki.module'
>>>> [[  list, of, definitions, to, export  ]]
>>
>>> Sure, with every syntax change, some existing code needs to be fixed. But in
>>> the case of this (proposed) change:
>>> a) there is not so much code to fix (cases like the above are rare), and
>>> b) the fix is local and trivial
>>
>> I have a *lot* of code relying on this behaviour.
>>
>> I use it for string building.
>>
>> local buf = { }
>> local function cat(v)
>>  buf[#buf + 1] = v
>>  return cat
>> end
>>
>> cat "foo " (bar) " baz"
>>
>> For complex cases like code generation string of calls can be quite
>> long. Also, adding extra braces would impact readability.
>>
>> Alexander.
>>
>
> I thought about mentioning this use case too. I agree that it's a
> useful pattern and would be a shame to lose it. But then I realised
> that the proposed change actually shouldn't affect it - there's no
> reason I can see why a string literal followed by a parenthesised
> expression, or vice versa, wouldn't still work exactly the same way.
> The only case that gets affected is when you have multiple string
> literals in a row, but in the specific case of string building, the
> net result happens to be exactly the same anyway - the strings are
> just concatenated at a different time.
>
> -Duncan
>