lua-users home
lua-l archive

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


On 20 December 2013 13:58, Andrew Starks <andrew.starks@trms.com> wrote:
> ```lua
> _ENV = {
>   print = print, string = string, table = table, pairs = pairs, type = type
> }
>
> do
>   local _string = string
>   local concat = table.concat
>   string = {}
>   for m_name, m_func in pairs(_string) do
>     string[m_name] = m_func
>   end
>
>   function string:map(...)
>     local args = type(...) == "table" and (...) or {...}
>
>     return self .. concat(args, self)
>
>   end
>
>
> end
> --testing
> --This is result that I want.
> print(string.map("test","this", "that"))
> -->testthistestthat
>
> --This is the syntax that I want to use, but it doesn't work...
> print(("test"):map("this", "that"))
> --lua: ...src\testing\test_string_library_question.lua:23: attempt to
> call method 'map' (a nil value)
> ```
> If I skip the parts where I hide my change from the global
> environment, then both function calls behave identically.
>
> Is there a way to patch the `string` library so that the changes apply
> to strings using the `self`/colon method, without patching `string`
> globally? Debug library?

All strings share the same metatable, which is a table whose __index
points to the `string` table:

> print(string)
table: 0x9d35000
> print( debug.getmetatable("hello") )
table: 0x9d34e88
> print( debug.getmetatable("world") )
table: 0x9d34e88
> print( debug.getmetatable("world").__index )
table: 0x9d35000

So yes, you can alter the behavior of strings' colon behavior without
patching `string` globally:

> print(("hello"):find("e"))
2    2
> another = {}; debug.setmetatable("world", { __index = another })
> print(("hello"):find("e"))
stdin:1: attempt to call method 'find' (a nil value)

...but that introduces a global change to your environment, anyway.

-- Hisham