[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Privately patching strings lib in Lua 5.2
- From: Hisham <h@...>
- Date: Fri, 20 Dec 2013 23:54:25 -0200
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