Pprint circular reference issues

Example 1

a, b, c = {}, {}, {}
a.a, a.b, a.c = a, b, c
b.a, b.b, b.c = a, b, c
c.a, c.b, c.c = a, b, c
pprint(a)

^ That code will crash the program (the editor is fine though).

Example 2

a, b = {}, {}
a.b = b
b.a = a
for i = 1, 23 do
	a[i] = i
	b[i] = i
end
pprint(a)
print("survived")

^ That code will print the following:

DEBUG:SCRIPT: 
{
  1 = 1,
  2 = 2,
  3 = 3,
  4 = 4,
  5 = 5,
  6 = 6,
  7 = 7,
  8 = 8,
  9 = 9,
  10 = 10,
  11 = 11,
  12 = 12,
  13 = 13,
  14 = 14,
  15 = 15,
  16 = 16,
  17 = 17,
  18 = 18,
  19 = 19,
  20 = 20,
  21 = 21,
  22 = 22,
  23 = 23,
  b = {
    1 = 1,
    2 = 2,
    3 = 3,
    4 = 4,
    5 = 5,
    6 = 6,
    7 = 7,
    8 = 8,
    9 = 9,
    10 = 10,
    11 = 11,
    12 = 12,
    13 = 13,
    14 = 14,
    15 = 15,
    16 = 16,
    17 = 17,
    18 = 18,
    19 = 19,
    20 = 20,
    21 = 21,
    22 = 22,
    23 = 23,
    a = {
      1 = 1,
      2 = 2,
      3 = 3,
      4 = 4,
      5 = 5,
      6 = 6,
      7 = 7,
      8 = 8,
      9 = 9,
      10 = 10,
      11 = 11,
      12 = 12,
      13 = 13,
      14 = 14,
      15 = 15,
      16 = 16,
      17 = 17,
      18 = 18,
      19 = 19,
      20 = 20,
      21 = 21,
      22 = 22,
      23 = 23,
      b = {
        1 = 1,
        2 = 2,
        3 = 3,
        4 = 4,
        5 = 5,
        6 = 6,
        7 = 7,
        8 = 8,
        9 = 9,
        10 = 10,
        11 = 11,
        12 = 12,
        13 = 13,
        14 = 14,
        15 = 15,
        16 = 16,
        17 = 17,
        18 = 18,
        19 = 19,
        20 = 20,
        21 = 21,
        22 = 22,
        23 = 23,
        a = {
          1 = 1,
          2 = 2,
          3 = 3,
          4 = 4,
          5 = 5,
          6 = 6,
          7 = 7,
          8 = 8,
          9 = 9,
          10 = 10,
          11 = 11,
          12 = 12,
          13 = 13,
          14 = 14,
          15 = 15,
          16 = 16,
          17 = 17,
          18 = 18,
          19 = 19,
          20 = 20,
          21 = 21,
          22 = 22,
          23 = 23,
          b = {
            1 = 1,
            2 = 2,
            3 = 3,
            4 = 4,
            5 = 5,
            6 = 6,
            7 = 7,
            8 = 8,
            9 = 9,
            10 = 10,
            11 = 11,
            12 = 12,
            13 = 13,
            14 = 14,
            15 = 15,
            16 = 16,
            17 = DEBUG:SCRIPT: survived

Seems like there’s a max string length for print and pprint and that the terminating newline isn’t counted as part of that limit, meaning the next thing printed after an overflowing string isn’t guaranteed to start on a line of it’s own.

Example 3

a = {}
b = {}
a.b = b
b.a = a
pprint(a)
print("survived")

^ That code will print the following:

DEBUG:SCRIPT: 
{
  b = {
    a = {
      b = {
        a = {
          b = {
            a = {
              b = {
                a = {
                  b = {
                    a = {
                      b = {
                        a = {
                          b = {
                            a = {
                              b = {
                                a = {
                                  b = {
                                    a = {
                                      b = {
                                        a = {
                                          b = {
                                            a = {
                                              b = {
                                                a = {
                                                  b = {
                                                    a = {
                                                      b = {
                                                        a = {
                                                          b = {
                                                            a = {
                                                              b = {
                                                                a...
                                                                Printing truncated. Circular refs?
                                                              }
                                                            }
                                                          }
                                                        }
                                                      }
                                                    }
                                                  }
                                                }
                                              }
                                            }
                                          }
                                        }
                                      }
        DEBUG:SCRIPT: survived

Again, the next message after pprinting the circular reference (“survived”) has been indented because the pprint string was cutoff without a terminating newline. Also it would be much more useful to detect the circular reference as soon as it starts and print something much nicer along the lines of:

DEBUG:SCRIPT: 
{
  b = {
    a = {
      Circular reference to table: 0x01234567
    }
  }
}

Requests

  1. When strings passed to print or pprint are too large there should still be a newline character at the end. Either that means adding a newline afterwards or it means printing one less character of the actual message and reserving the last character for a newline.
  2. Detect and handle circular references much earlier in pprint and provide a more detailed and useful output such as the address of whatever table the loop starts on
3 Likes

Actually, even better than just guaranteeing the newline when trying to print a too-large string would be printing a follow-up message explicitly pointing out that the previous message was truncated.

e.g.

DEBUG:SCRIPT: <super long message that gets truncated, with a guaranteed newline at the end>
DEBUG:ENGINE: The previous message was truncated as it was too long
4 Likes