@ -10,90 +10,222 @@ The objective here is human understanding (i.e. for debugging), not serializatio
Examples of use
Examples of use
===============
===============
`inspect` has the following declaration: `str = inspect(value, <options>)`.
`inspect` has the following declaration: `local str = inspect(value, <options>)`.
`value` can be any Lua value. `inspect` transforms simple types (like strings or numbers) into strings. Tables, on the other
`value` can be any Lua value.
hand, are rendered in a way a human can undersand.
`inspect` transforms simple types (like strings or numbers) into strings.
```lua
assert(inspect(1) == "1")
assert(inspect("Hello") == '"Hello"')
```
Tables, on the other hand, are rendered in a way a human can read easily.
"Array-like" tables are rendered horizontally:
"Array-like" tables are rendered horizontally:
inspect({1,2,3,4}) == "{ 1, 2, 3, 4 }"
```lua
assert(inspect({1,2,3,4}) == "{ 1, 2, 3, 4 }")
```
"dictionary-like" tables are rendered with one element per line:
"Dictionary-like" tables are rendered with one element per line:
inspect({a=1,b=2}) == [[{
```lua
a = 1,
assert(inspect({a=1,b=2}) == [[{
b = 2
a = 1,
}]]
b = 2
}]])
```
The keys will be sorted alphanumerically when possible.
The keys will be sorted alphanumerically when possible.
"Hybrid" tables will have the array part on the first line, and the dictionary part just below them:
"Hybrid" tables will have the array part on the first line, and the dictionary part just below them:
inspect({1,2,3,b=2,a=1}) == [[{ 1, 2, 3,
```lua
a = 1,
assert(inspect({1,2,3,b=2,a=1}) == [[{ 1, 2, 3,
b = 2
a = 1,
}]]
b = 2
}]])
```
Tables can be nested, and will be indented with two spaces per level.
Subtables are indented with two spaces per level.
inspect({a={b=2}}) == [[{
```lua
a = {
assert(inspect({a={b=2}}) == [[{
b = 2
a = {
}
b = 2
}]]
}
}]])
```
Functions, userdata and any other custom types from Luajit are simply as `<function x>`, `<userdata x>`, etc.:
Functions, userdata and any other custom types from Luajit are simply as `<function x>`, `<userdata x>`, etc.:
inspect({ f = print, ud = some_user_data, thread = a_thread} ) == [[{
```lua
f = <function1>,
assert(inspect({ f = print, ud = some_user_data, thread = a_thread} ) == [[{
u = <userdata1>,
f = <function1>,
thread = <thread1>
u = <userdata1>,
}]])
thread = <thread1>
}]])
```
If the table has a metatable, inspect will include it at the end, in a special field called `<metatable>`:
If the table has a metatable, inspect will include it at the end, in a special field called `<metatable>`:
inspect(setmetatable({a=1}, {b=2}) == [[{
```lua
a = 1
assert(inspect(setmetatable({a=1}, {b=2}) == [[{
<metatable> = {
a = 1
b = 2
<metatable> = {
}
b = 2
}]])
}
}]]))
```
`inspect` can handle tables with loops inside them. It will print `<id>` right before the table is printed out the first time, and replace the whole table with `<table id>` from then on, preventing infinite loops.
`inspect` can handle tables with loops inside them. It will print `<id>` right before the table is printed out the first time, and replace the whole table with `<table id>` from then on, preventing infinite loops.
Notice that since both `a` appears more than once in the expression, it is prefixed by `<1>` and replaced by `<table 1>` every time it appears later on.
Notice that since both `a` appears more than once in the expression, it is prefixed by `<1>` and replaced by `<table 1>` every time it appears later on.
### options.depth
### options
`inspect`'s second parameter allows controlling the maximum depth that will be printed out. When the max depth is reached, it'll just return `{...}`:
`inspect` has a second parameter, called `options`. It is not mandatory, but when it is provided, it must be a table.
local t5 = {a = {b = {c = {d = {e = 5}}}}}
#### options.depth
inspect(t5, {depth = 4}) == [[{
`options.depth` sets the maximum depth that will be printed out.
a = {
When the max depth is reached, `inspect` will stop parsing tables and just return `{...}`:
b = {
c = {
```lua
d = {...}
}
}
}
}]]
inspect(t5, {depth = 2}) == [[{
local t5 = {a = {b = {c = {d = {e = 5}}}}}
a = {
b = {...}
assert(inspect(t5, {depth = 4}) == [[{
a = {
b = {
c = {
d = {...}
}
}
}]])
}
}
}]])
assert(inspect(t5, {depth = 2}) == [[{
a = {
b = {...}
}
}]])
```
`options.depth` defaults to infinite (`math.huge`).
`options.depth` defaults to infinite (`math.huge`).
### options.filter
### options.newline & options.indent
These are the strings used by `inspect` to respectively add a newline and indent each level of a table.
By default, `options.newline` is `"\n"` and `options.indent` is `" "` (two spaces).
Sometimes it might be convenient to "filter out" some parts of the output. The `options.filter` option can do that.
Sometimes it might be convenient to "filter out" some parts of the output. The `options.filter` option can do that.
@ -116,14 +248,14 @@ Sometimes it might be convenient to "filter out" some parts of the output. The `
Gotchas / Warnings
Gotchas / Warnings
==================
==================
This method is *not* appropiate for saving/restoring tables. It is ment to be used by the programmer mainly while debugging a program.
This method is *not* appropriate for saving/restoring tables. It is meant to be used by the programmer mainly while debugging a program.
Installation
Installation
============
============
Just copy the inspect.lua file somewhere in your projects (maybe inside a /lib/ folder) and require it accordingly.
Just copy the inspect.lua file somewhere in your projects (maybe inside a /lib/ folder) and require it accordingly.
Remember to store the value returned by require somewhere! (I suggest a local variable named inspect, altough others might like table.inspect)
Remember to store the value returned by require somewhere! (I suggest a local variable named inspect, although others might like table.inspect)
local inspect = require 'inspect'
local inspect = require 'inspect'
-- or --
-- or --
@ -134,7 +266,7 @@ Also, make sure to read the license file; the text of that license file must app
Specs
Specs
=====
=====
This project uses [busted](http://olivinelabs.com/busted/) for its specs. If you want to run the specs, you will have to install telescope first. Then just execute the following from the root inspect folder:
This project uses [busted](http://olivinelabs.com/busted/) for its specs. If you want to run the specs, you will have to install busted first. Then just execute the following from the root inspect folder: