[{"data":1,"prerenderedAt":5864},["ShallowReactive",2],{"page-\u002Flua\u002F05-tables-and-objects":3},{"id":4,"title":5,"body":6,"description":5855,"extension":5856,"meta":5857,"navigation":79,"path":5858,"seo":5859,"stem":5862,"__hash__":5863},"content\u002Flua\u002F05-tables-and-objects.md","Lua 05 — Tables, OOP, Copy Semantics & Data Structures",{"type":7,"value":8,"toc":5846},"minimark",[9,14,36,41,4960,4968,5078,5086,5146,5150,5158,5205,5215,5387,5398,5466,5475,5479,5842],[10,11,13],"h1",{"id":12},"_05-tables-oop-copy-semantics-data-structures","05 — Tables, OOP, Copy Semantics & Data Structures",[15,16,17,18,22,23,26,27,30,31,35],"p",{},"Tables are Lua's ",[19,20,21],"strong",{},"only composite data structure",". They serve as arrays, dictionaries, objects, classes, sets, and namespaces. Internally, each table has an ",[19,24,25],{},"array part"," (1..n, contiguous) and a ",[19,28,29],{},"hash part"," (all other keys). The boundary is determined by a rehash algorithm. Understanding copy semantics (reference vs value), OOP patterns via ",[32,33,34],"code",{},"__index",", and how to build production data structures is the core of writing non-trivial Lua.",[37,38,40],"h2",{"id":39},"table-internals-array-part-vs-hash-part","Table Internals: Array Part vs Hash Part",[42,43,45,337,342,507,511,1506,1510],"code-wrapper",{"language":44},"lua",[46,47,51],"pre",{"className":48,"code":49,"language":44,"meta":50,"style":50},"language-lua shiki shiki-themes github-light github-dark","-- The array part stores keys 1..n contiguously (C array — O(1) access)\n-- The hash part stores everything else (hash table — O(1) amortized)\n-- The VM automatically decides the split during rehash (triggered on insertion)\n\nlocal t = {10, 20, 30}       -- array part: [1]=10, [2]=20, [3]=30\nt.name = \"Alice\"             -- hash part: name=\"Alice\"\nt[5] = 50                    -- hash part (non-contiguous: gap at 4)\nt[4] = 40                    -- NOW contiguous 1..5 → rehash moves 4,5 to array part\n#t                           -- 5 (length of array part)\n\n-- Constructor: positional args go to array part, named to hash part\nlocal mixed = {\n  100, 200,                  -- array: [1]=100, [2]=200\n  name = \"test\",             -- hash:  name=\"test\"\n  [10] = \"x\",                -- hash:  [10]=\"x\" (non-contiguous)\n}\n\n-- The # operator: returns ANY n where t[n] ~= nil and t[n+1] == nil\n-- For contiguous arrays, this is the length. For sparse arrays, undefined.\nlocal sparse = {1, 2, nil, 4}  -- literal: actually {1, 2, [4]=4} — key 3 doesn't exist\n#sparse                      -- 2 (any border 2 or 4 is valid; impl-dependent)\n","",[32,52,53,62,68,74,81,119,139,159,177,189,194,200,213,230,247,268,274,279,285,291,326],{"__ignoreMap":50},[54,55,58],"span",{"class":56,"line":57},"line",1,[54,59,61],{"class":60},"sdCPZ","-- The array part stores keys 1..n contiguously (C array — O(1) access)\n",[54,63,65],{"class":56,"line":64},2,[54,66,67],{"class":60},"-- The hash part stores everything else (hash table — O(1) amortized)\n",[54,69,71],{"class":56,"line":70},3,[54,72,73],{"class":60},"-- The VM automatically decides the split during rehash (triggered on insertion)\n",[54,75,77],{"class":56,"line":76},4,[54,78,80],{"emptyLinePlaceholder":79},true,"\n",[54,82,84,88,92,95,98,102,105,108,110,113,116],{"class":56,"line":83},5,[54,85,87],{"class":86},"svdQ7","local",[54,89,91],{"class":90},"ssxIu"," t ",[54,93,94],{"class":86},"=",[54,96,97],{"class":90}," {",[54,99,101],{"class":100},"snvgF","10",[54,103,104],{"class":90},", ",[54,106,107],{"class":100},"20",[54,109,104],{"class":90},[54,111,112],{"class":100},"30",[54,114,115],{"class":90},"}       ",[54,117,118],{"class":60},"-- array part: [1]=10, [2]=20, [3]=30\n",[54,120,122,125,129,132,136],{"class":56,"line":121},6,[54,123,124],{"class":90},"t.",[54,126,128],{"class":127},"sIsaT","name",[54,130,131],{"class":86}," =",[54,133,135],{"class":134},"sJ6F3"," \"Alice\"             ",[54,137,138],{"class":60},"-- hash part: name=\"Alice\"\n",[54,140,142,145,148,151,153,156],{"class":56,"line":141},7,[54,143,144],{"class":90},"t[",[54,146,147],{"class":100},"5",[54,149,150],{"class":90},"] ",[54,152,94],{"class":86},[54,154,155],{"class":100}," 50",[54,157,158],{"class":60},"                    -- hash part (non-contiguous: gap at 4)\n",[54,160,162,164,167,169,171,174],{"class":56,"line":161},8,[54,163,144],{"class":90},[54,165,166],{"class":100},"4",[54,168,150],{"class":90},[54,170,94],{"class":86},[54,172,173],{"class":100}," 40",[54,175,176],{"class":60},"                    -- NOW contiguous 1..5 → rehash moves 4,5 to array part\n",[54,178,180,183,186],{"class":56,"line":179},9,[54,181,182],{"class":86},"#",[54,184,185],{"class":90},"t                           ",[54,187,188],{"class":60},"-- 5 (length of array part)\n",[54,190,192],{"class":56,"line":191},10,[54,193,80],{"emptyLinePlaceholder":79},[54,195,197],{"class":56,"line":196},11,[54,198,199],{"class":60},"-- Constructor: positional args go to array part, named to hash part\n",[54,201,203,205,208,210],{"class":56,"line":202},12,[54,204,87],{"class":86},[54,206,207],{"class":90}," mixed ",[54,209,94],{"class":86},[54,211,212],{"class":90}," {\n",[54,214,216,219,221,224,227],{"class":56,"line":215},13,[54,217,218],{"class":100},"  100",[54,220,104],{"class":90},[54,222,223],{"class":100},"200",[54,225,226],{"class":90},",                  ",[54,228,229],{"class":60},"-- array: [1]=100, [2]=200\n",[54,231,233,236,238,241,244],{"class":56,"line":232},14,[54,234,235],{"class":90},"  name ",[54,237,94],{"class":86},[54,239,240],{"class":134}," \"test\"",[54,242,243],{"class":90},",             ",[54,245,246],{"class":60},"-- hash:  name=\"test\"\n",[54,248,250,253,255,257,259,262,265],{"class":56,"line":249},15,[54,251,252],{"class":90},"  [",[54,254,101],{"class":100},[54,256,150],{"class":90},[54,258,94],{"class":86},[54,260,261],{"class":134}," \"x\"",[54,263,264],{"class":90},",                ",[54,266,267],{"class":60},"-- hash:  [10]=\"x\" (non-contiguous)\n",[54,269,271],{"class":56,"line":270},16,[54,272,273],{"class":90},"}\n",[54,275,277],{"class":56,"line":276},17,[54,278,80],{"emptyLinePlaceholder":79},[54,280,282],{"class":56,"line":281},18,[54,283,284],{"class":60},"-- The # operator: returns ANY n where t[n] ~= nil and t[n+1] == nil\n",[54,286,288],{"class":56,"line":287},19,[54,289,290],{"class":60},"-- For contiguous arrays, this is the length. For sparse arrays, undefined.\n",[54,292,294,296,299,301,303,306,308,311,313,316,318,320,323],{"class":56,"line":293},20,[54,295,87],{"class":86},[54,297,298],{"class":90}," sparse ",[54,300,94],{"class":86},[54,302,97],{"class":90},[54,304,305],{"class":100},"1",[54,307,104],{"class":90},[54,309,310],{"class":100},"2",[54,312,104],{"class":90},[54,314,315],{"class":100},"nil",[54,317,104],{"class":90},[54,319,166],{"class":100},[54,321,322],{"class":90},"}  ",[54,324,325],{"class":60},"-- literal: actually {1, 2, [4]=4} — key 3 doesn't exist\n",[54,327,329,331,334],{"class":56,"line":328},21,[54,330,182],{"class":86},[54,332,333],{"class":90},"sparse                      ",[54,335,336],{"class":60},"-- 2 (any border 2 or 4 is valid; impl-dependent)\n",[338,339,341],"h3",{"id":340},"edge-case-rehash-triggers-and-array-part-growth","Edge case: rehash triggers and array part growth",[42,343,344],{"language":44},[46,345,347],{"className":48,"code":346,"language":44,"meta":50,"style":50},"-- Each insertion that hits a new hash key may trigger a rehash if the hash part is full.\n-- Rehash: O(n) — resizes both parts, reinserts all entries.\n-- Anti-pattern: building a large array one element at a time triggers log(n) rehashes.\n\n-- BAD: N rehashes for N insertions (amortized O(1) but with allocation spikes)\nlocal t = {}\nfor i = 1, 1000000 do\n  t[i] = i  -- triggers rehash at powers of 2: 2, 4, 8, ... 524288, 1048576\nend\n\n-- GOOD: pre-allocate by filling the array part in one shot (constructor or loop)\nlocal t = {}\nfor i = 1, 1000000 do\n  t[i] = 0  -- still triggers rehashes, but at least the values are cheap\nend\n-- BEST: if you know the size, use a single constructor or set all at once\nlocal t = table.pack(table.unpack({}))  -- no, just use a loop and accept it\n-- Lua doesn't expose a \"reserve\" API. The rehash doubling strategy is amortized O(1).\n",[32,348,349,354,359,364,368,373,384,405,418,423,427,432,442,458,470,474,479,502],{"__ignoreMap":50},[54,350,351],{"class":56,"line":57},[54,352,353],{"class":60},"-- Each insertion that hits a new hash key may trigger a rehash if the hash part is full.\n",[54,355,356],{"class":56,"line":64},[54,357,358],{"class":60},"-- Rehash: O(n) — resizes both parts, reinserts all entries.\n",[54,360,361],{"class":56,"line":70},[54,362,363],{"class":60},"-- Anti-pattern: building a large array one element at a time triggers log(n) rehashes.\n",[54,365,366],{"class":56,"line":76},[54,367,80],{"emptyLinePlaceholder":79},[54,369,370],{"class":56,"line":83},[54,371,372],{"class":60},"-- BAD: N rehashes for N insertions (amortized O(1) but with allocation spikes)\n",[54,374,375,377,379,381],{"class":56,"line":121},[54,376,87],{"class":86},[54,378,91],{"class":90},[54,380,94],{"class":86},[54,382,383],{"class":90}," {}\n",[54,385,386,389,392,394,397,399,402],{"class":56,"line":141},[54,387,388],{"class":86},"for",[54,390,391],{"class":90}," i ",[54,393,94],{"class":86},[54,395,396],{"class":100}," 1",[54,398,104],{"class":90},[54,400,401],{"class":100},"1000000",[54,403,404],{"class":86}," do\n",[54,406,407,410,412,415],{"class":56,"line":161},[54,408,409],{"class":90},"  t[i] ",[54,411,94],{"class":86},[54,413,414],{"class":90}," i  ",[54,416,417],{"class":60},"-- triggers rehash at powers of 2: 2, 4, 8, ... 524288, 1048576\n",[54,419,420],{"class":56,"line":179},[54,421,422],{"class":86},"end\n",[54,424,425],{"class":56,"line":191},[54,426,80],{"emptyLinePlaceholder":79},[54,428,429],{"class":56,"line":196},[54,430,431],{"class":60},"-- GOOD: pre-allocate by filling the array part in one shot (constructor or loop)\n",[54,433,434,436,438,440],{"class":56,"line":202},[54,435,87],{"class":86},[54,437,91],{"class":90},[54,439,94],{"class":86},[54,441,383],{"class":90},[54,443,444,446,448,450,452,454,456],{"class":56,"line":215},[54,445,388],{"class":86},[54,447,391],{"class":90},[54,449,94],{"class":86},[54,451,396],{"class":100},[54,453,104],{"class":90},[54,455,401],{"class":100},[54,457,404],{"class":86},[54,459,460,462,464,467],{"class":56,"line":232},[54,461,409],{"class":90},[54,463,94],{"class":86},[54,465,466],{"class":100}," 0",[54,468,469],{"class":60},"  -- still triggers rehashes, but at least the values are cheap\n",[54,471,472],{"class":56,"line":249},[54,473,422],{"class":86},[54,475,476],{"class":56,"line":270},[54,477,478],{"class":60},"-- BEST: if you know the size, use a single constructor or set all at once\n",[54,480,481,483,485,487,490,493,496,499],{"class":56,"line":276},[54,482,87],{"class":86},[54,484,91],{"class":90},[54,486,94],{"class":86},[54,488,489],{"class":100}," table.pack",[54,491,492],{"class":90},"(",[54,494,495],{"class":100},"table.unpack",[54,497,498],{"class":90},"({}))  ",[54,500,501],{"class":60},"-- no, just use a loop and accept it\n",[54,503,504],{"class":56,"line":281},[54,505,506],{"class":60},"-- Lua doesn't expose a \"reserve\" API. The rehash doubling strategy is amortized O(1).\n",[37,508,510],{"id":509},"reference-vs-value-semantics","Reference vs Value Semantics",[42,512,513,771,775],{"language":44},[46,514,516],{"className":48,"code":515,"language":44,"meta":50,"style":50},"-- Tables are REFERENCE types: assignment copies the reference, not the data\nlocal a = {x = 1}\nlocal b = a           -- b and a point to the SAME table object\nb.x = 99\nprint(a.x)            -- 99 (same object)\n\n-- Passing to a function: also passes the reference (mutation visible to caller)\nlocal function mutate(t)\n  t.x = t.x + 1       -- mutates the caller's table\nend\nlocal data = {x = 10}\nmutate(data)\nprint(data.x)         -- 11\n\n-- Identity check: == compares references, NOT content\nlocal t1, t2 = {1,2}, {1,2}\nprint(t1 == t2)       -- false (different objects, even if content identical)\nprint(t1 == t1)       -- true (same object)\n\n-- Strings ARE compared by content (interned)\nprint(\"hello\" == \"hello\")  -- true (same interned string object)\n",[32,517,518,523,541,556,569,585,589,594,607,629,633,651,659,674,678,683,712,728,742,746,751],{"__ignoreMap":50},[54,519,520],{"class":56,"line":57},[54,521,522],{"class":60},"-- Tables are REFERENCE types: assignment copies the reference, not the data\n",[54,524,525,527,530,532,535,537,539],{"class":56,"line":64},[54,526,87],{"class":86},[54,528,529],{"class":90}," a ",[54,531,94],{"class":86},[54,533,534],{"class":90}," {x ",[54,536,94],{"class":86},[54,538,396],{"class":100},[54,540,273],{"class":90},[54,542,543,545,548,550,553],{"class":56,"line":70},[54,544,87],{"class":86},[54,546,547],{"class":90}," b ",[54,549,94],{"class":86},[54,551,552],{"class":90}," a           ",[54,554,555],{"class":60},"-- b and a point to the SAME table object\n",[54,557,558,561,564,566],{"class":56,"line":76},[54,559,560],{"class":90},"b.",[54,562,563],{"class":127},"x",[54,565,131],{"class":86},[54,567,568],{"class":100}," 99\n",[54,570,571,574,577,579,582],{"class":56,"line":83},[54,572,573],{"class":100},"print",[54,575,576],{"class":90},"(a.",[54,578,563],{"class":127},[54,580,581],{"class":90},")            ",[54,583,584],{"class":60},"-- 99 (same object)\n",[54,586,587],{"class":56,"line":121},[54,588,80],{"emptyLinePlaceholder":79},[54,590,591],{"class":56,"line":141},[54,592,593],{"class":60},"-- Passing to a function: also passes the reference (mutation visible to caller)\n",[54,595,596,598,601,604],{"class":56,"line":161},[54,597,87],{"class":86},[54,599,600],{"class":86}," function",[54,602,603],{"class":127}," mutate",[54,605,606],{"class":90},"(t)\n",[54,608,609,612,614,616,619,621,624,626],{"class":56,"line":179},[54,610,611],{"class":90},"  t.",[54,613,563],{"class":127},[54,615,131],{"class":86},[54,617,618],{"class":90}," t.",[54,620,563],{"class":127},[54,622,623],{"class":86}," +",[54,625,396],{"class":100},[54,627,628],{"class":60},"       -- mutates the caller's table\n",[54,630,631],{"class":56,"line":191},[54,632,422],{"class":86},[54,634,635,637,640,642,644,646,649],{"class":56,"line":196},[54,636,87],{"class":86},[54,638,639],{"class":90}," data ",[54,641,94],{"class":86},[54,643,534],{"class":90},[54,645,94],{"class":86},[54,647,648],{"class":100}," 10",[54,650,273],{"class":90},[54,652,653,656],{"class":56,"line":202},[54,654,655],{"class":100},"mutate",[54,657,658],{"class":90},"(data)\n",[54,660,661,663,666,668,671],{"class":56,"line":215},[54,662,573],{"class":100},[54,664,665],{"class":90},"(data.",[54,667,563],{"class":127},[54,669,670],{"class":90},")         ",[54,672,673],{"class":60},"-- 11\n",[54,675,676],{"class":56,"line":232},[54,677,80],{"emptyLinePlaceholder":79},[54,679,680],{"class":56,"line":249},[54,681,682],{"class":60},"-- Identity check: == compares references, NOT content\n",[54,684,685,687,690,692,694,696,699,701,704,706,708,710],{"class":56,"line":270},[54,686,87],{"class":86},[54,688,689],{"class":90}," t1, t2 ",[54,691,94],{"class":86},[54,693,97],{"class":90},[54,695,305],{"class":100},[54,697,698],{"class":90},",",[54,700,310],{"class":100},[54,702,703],{"class":90},"}, {",[54,705,305],{"class":100},[54,707,698],{"class":90},[54,709,310],{"class":100},[54,711,273],{"class":90},[54,713,714,716,719,722,725],{"class":56,"line":276},[54,715,573],{"class":100},[54,717,718],{"class":90},"(t1 ",[54,720,721],{"class":86},"==",[54,723,724],{"class":90}," t2)       ",[54,726,727],{"class":60},"-- false (different objects, even if content identical)\n",[54,729,730,732,734,736,739],{"class":56,"line":281},[54,731,573],{"class":100},[54,733,718],{"class":90},[54,735,721],{"class":86},[54,737,738],{"class":90}," t1)       ",[54,740,741],{"class":60},"-- true (same object)\n",[54,743,744],{"class":56,"line":287},[54,745,80],{"emptyLinePlaceholder":79},[54,747,748],{"class":56,"line":293},[54,749,750],{"class":60},"-- Strings ARE compared by content (interned)\n",[54,752,753,755,757,760,762,765,768],{"class":56,"line":328},[54,754,573],{"class":100},[54,756,492],{"class":90},[54,758,759],{"class":134},"\"hello\" ",[54,761,721],{"class":86},[54,763,764],{"class":134}," \"hello\"",[54,766,767],{"class":90},")  ",[54,769,770],{"class":60},"-- true (same interned string object)\n",[37,772,774],{"id":773},"shallow-vs-deep-copy","Shallow vs Deep Copy",[42,776,777,1217,1221],{"language":44},[46,778,780],{"className":48,"code":779,"language":44,"meta":50,"style":50},"-- Shallow copy: copy top-level keys; nested tables are still shared references\nlocal function shallow_copy(t)\n  local c = {}\n  for k, v in pairs(t) do\n    c[k] = v  -- if v is a table, c[k] and t[k] point to the SAME nested table\n  end\n  return c\nend\n\nlocal original = {a = 1, nested = {b = 2}}\nlocal copy = shallow_copy(original)\ncopy.a = 99\ncopy.nested.b = 999\nprint(original.a)        -- 1 (not affected — top-level copy)\nprint(original.nested.b) -- 999 (AFFECTED — nested table is shared!)\n\n-- Deep copy: recursively copy nested tables. Handles cycles via memo table.\nlocal function deep_copy(t, seen)\n  seen = seen or {}\n  if seen[t] then return seen[t] end  -- cycle detected — return existing copy\n  if type(t) ~= \"table\" then return t end  -- non-table: return as-is (value type)\n  local c = {}\n  seen[t] = c  -- register before recursing (for cycles)\n  for k, v in pairs(t) do\n    c[deep_copy(k, seen)] = deep_copy(v, seen)  -- keys can also be tables (rare)\n  end\n  return setmetatable(c, getmetatable(t))  -- preserve metatable\nend\n\nlocal cyclic = {}\ncyclic.self = cyclic  -- self-referential\nlocal safe = deep_copy(cyclic)\nprint(safe.self == safe)  -- true (cycle preserved correctly, no infinite loop)\n",[32,781,782,787,798,810,830,843,848,856,860,864,896,910,922,940,955,973,977,982,994,1009,1031,1057,1068,1082,1097,1119,1124,1144,1149,1154,1166,1183,1198],{"__ignoreMap":50},[54,783,784],{"class":56,"line":57},[54,785,786],{"class":60},"-- Shallow copy: copy top-level keys; nested tables are still shared references\n",[54,788,789,791,793,796],{"class":56,"line":64},[54,790,87],{"class":86},[54,792,600],{"class":86},[54,794,795],{"class":127}," shallow_copy",[54,797,606],{"class":90},[54,799,800,803,806,808],{"class":56,"line":70},[54,801,802],{"class":86},"  local",[54,804,805],{"class":90}," c ",[54,807,94],{"class":86},[54,809,383],{"class":90},[54,811,812,815,818,821,824,827],{"class":56,"line":76},[54,813,814],{"class":86},"  for",[54,816,817],{"class":90}," k, v ",[54,819,820],{"class":86},"in",[54,822,823],{"class":100}," pairs",[54,825,826],{"class":90},"(t) ",[54,828,829],{"class":86},"do\n",[54,831,832,835,837,840],{"class":56,"line":83},[54,833,834],{"class":90},"    c[k] ",[54,836,94],{"class":86},[54,838,839],{"class":90}," v  ",[54,841,842],{"class":60},"-- if v is a table, c[k] and t[k] point to the SAME nested table\n",[54,844,845],{"class":56,"line":121},[54,846,847],{"class":86},"  end\n",[54,849,850,853],{"class":56,"line":141},[54,851,852],{"class":86},"  return",[54,854,855],{"class":90}," c\n",[54,857,858],{"class":56,"line":161},[54,859,422],{"class":86},[54,861,862],{"class":56,"line":179},[54,863,80],{"emptyLinePlaceholder":79},[54,865,866,868,871,873,876,878,880,883,885,888,890,893],{"class":56,"line":191},[54,867,87],{"class":86},[54,869,870],{"class":90}," original ",[54,872,94],{"class":86},[54,874,875],{"class":90}," {a ",[54,877,94],{"class":86},[54,879,396],{"class":100},[54,881,882],{"class":90},", nested ",[54,884,94],{"class":86},[54,886,887],{"class":90}," {b ",[54,889,94],{"class":86},[54,891,892],{"class":100}," 2",[54,894,895],{"class":90},"}}\n",[54,897,898,900,903,905,907],{"class":56,"line":196},[54,899,87],{"class":86},[54,901,902],{"class":90}," copy ",[54,904,94],{"class":86},[54,906,795],{"class":100},[54,908,909],{"class":90},"(original)\n",[54,911,912,915,918,920],{"class":56,"line":202},[54,913,914],{"class":90},"copy.",[54,916,917],{"class":127},"a",[54,919,131],{"class":86},[54,921,568],{"class":100},[54,923,924,926,929,932,935,937],{"class":56,"line":215},[54,925,914],{"class":90},[54,927,928],{"class":127},"nested",[54,930,931],{"class":90},".",[54,933,934],{"class":127},"b",[54,936,131],{"class":86},[54,938,939],{"class":100}," 999\n",[54,941,942,944,947,949,952],{"class":56,"line":232},[54,943,573],{"class":100},[54,945,946],{"class":90},"(original.",[54,948,917],{"class":127},[54,950,951],{"class":90},")        ",[54,953,954],{"class":60},"-- 1 (not affected — top-level copy)\n",[54,956,957,959,961,963,965,967,970],{"class":56,"line":249},[54,958,573],{"class":100},[54,960,946],{"class":90},[54,962,928],{"class":127},[54,964,931],{"class":90},[54,966,934],{"class":127},[54,968,969],{"class":90},") ",[54,971,972],{"class":60},"-- 999 (AFFECTED — nested table is shared!)\n",[54,974,975],{"class":56,"line":270},[54,976,80],{"emptyLinePlaceholder":79},[54,978,979],{"class":56,"line":276},[54,980,981],{"class":60},"-- Deep copy: recursively copy nested tables. Handles cycles via memo table.\n",[54,983,984,986,988,991],{"class":56,"line":281},[54,985,87],{"class":86},[54,987,600],{"class":86},[54,989,990],{"class":127}," deep_copy",[54,992,993],{"class":90},"(t, seen)\n",[54,995,996,999,1001,1004,1007],{"class":56,"line":287},[54,997,998],{"class":90},"  seen ",[54,1000,94],{"class":86},[54,1002,1003],{"class":90}," seen ",[54,1005,1006],{"class":86},"or",[54,1008,383],{"class":90},[54,1010,1011,1014,1017,1020,1023,1025,1028],{"class":56,"line":293},[54,1012,1013],{"class":86},"  if",[54,1015,1016],{"class":90}," seen[t] ",[54,1018,1019],{"class":86},"then",[54,1021,1022],{"class":86}," return",[54,1024,1016],{"class":90},[54,1026,1027],{"class":86},"end",[54,1029,1030],{"class":60},"  -- cycle detected — return existing copy\n",[54,1032,1033,1035,1038,1040,1043,1046,1048,1050,1052,1054],{"class":56,"line":328},[54,1034,1013],{"class":86},[54,1036,1037],{"class":100}," type",[54,1039,826],{"class":90},[54,1041,1042],{"class":86},"~=",[54,1044,1045],{"class":134}," \"table\" ",[54,1047,1019],{"class":86},[54,1049,1022],{"class":86},[54,1051,91],{"class":90},[54,1053,1027],{"class":86},[54,1055,1056],{"class":60},"  -- non-table: return as-is (value type)\n",[54,1058,1060,1062,1064,1066],{"class":56,"line":1059},22,[54,1061,802],{"class":86},[54,1063,805],{"class":90},[54,1065,94],{"class":86},[54,1067,383],{"class":90},[54,1069,1071,1074,1076,1079],{"class":56,"line":1070},23,[54,1072,1073],{"class":90},"  seen[t] ",[54,1075,94],{"class":86},[54,1077,1078],{"class":90}," c  ",[54,1080,1081],{"class":60},"-- register before recursing (for cycles)\n",[54,1083,1085,1087,1089,1091,1093,1095],{"class":56,"line":1084},24,[54,1086,814],{"class":86},[54,1088,817],{"class":90},[54,1090,820],{"class":86},[54,1092,823],{"class":100},[54,1094,826],{"class":90},[54,1096,829],{"class":86},[54,1098,1100,1103,1106,1109,1111,1113,1116],{"class":56,"line":1099},25,[54,1101,1102],{"class":90},"    c[",[54,1104,1105],{"class":100},"deep_copy",[54,1107,1108],{"class":90},"(k, seen)] ",[54,1110,94],{"class":86},[54,1112,990],{"class":100},[54,1114,1115],{"class":90},"(v, seen)  ",[54,1117,1118],{"class":60},"-- keys can also be tables (rare)\n",[54,1120,1122],{"class":56,"line":1121},26,[54,1123,847],{"class":86},[54,1125,1127,1129,1132,1135,1138,1141],{"class":56,"line":1126},27,[54,1128,852],{"class":86},[54,1130,1131],{"class":100}," setmetatable",[54,1133,1134],{"class":90},"(c, ",[54,1136,1137],{"class":100},"getmetatable",[54,1139,1140],{"class":90},"(t))  ",[54,1142,1143],{"class":60},"-- preserve metatable\n",[54,1145,1147],{"class":56,"line":1146},28,[54,1148,422],{"class":86},[54,1150,1152],{"class":56,"line":1151},29,[54,1153,80],{"emptyLinePlaceholder":79},[54,1155,1157,1159,1162,1164],{"class":56,"line":1156},30,[54,1158,87],{"class":86},[54,1160,1161],{"class":90}," cyclic ",[54,1163,94],{"class":86},[54,1165,383],{"class":90},[54,1167,1169,1172,1175,1177,1180],{"class":56,"line":1168},31,[54,1170,1171],{"class":90},"cyclic.",[54,1173,1174],{"class":127},"self",[54,1176,131],{"class":86},[54,1178,1179],{"class":90}," cyclic  ",[54,1181,1182],{"class":60},"-- self-referential\n",[54,1184,1186,1188,1191,1193,1195],{"class":56,"line":1185},32,[54,1187,87],{"class":86},[54,1189,1190],{"class":90}," safe ",[54,1192,94],{"class":86},[54,1194,990],{"class":100},[54,1196,1197],{"class":90},"(cyclic)\n",[54,1199,1201,1203,1206,1208,1211,1214],{"class":56,"line":1200},33,[54,1202,573],{"class":100},[54,1204,1205],{"class":90},"(safe.",[54,1207,1174],{"class":127},[54,1209,1210],{"class":86}," ==",[54,1212,1213],{"class":90}," safe)  ",[54,1215,1216],{"class":60},"-- true (cycle preserved correctly, no infinite loop)\n",[338,1218,1220],{"id":1219},"anti-pattern-shared-default-table-in-function-parameters","Anti-pattern: shared default table in function parameters",[42,1222,1223],{"language":44},[46,1224,1226],{"className":48,"code":1225,"language":44,"meta":50,"style":50},"-- BAD: default table is shared across all calls — mutations persist!\nlocal function process(data)\n  data = data or {}  -- if nil, uses the SAME {} every call? NO — Lua creates fresh {} per call\n  -- Actually this is safe in Lua! Unlike Python's mutable default args, Lua's\n  -- `or {}` evaluates the {} constructor fresh each call. This is fine.\n  data.count = (data.count or 0) + 1\n  return data\nend\nprocess().count  -- 1\nprocess().count  -- 1 (fresh table each call — safe)\n\n-- The REAL trap: default table stored in an upvalue (shared)\nlocal default_opts = {verbose = false, timeout = 5000}  -- shared object!\nlocal function process2(opts)\n  opts = opts or default_opts  -- if caller passes nothing, uses SHARED default_opts\n  opts.verbose = true  -- MUTATES the shared default!\n  -- Next call with no args: opts.verbose is NOW true (leaked state)\nend\nprocess2()\nprocess2()  -- default_opts.verbose is now true — BUG\n\n-- FIX: copy the defaults, don't share the reference\nlocal function process3(opts)\n  opts = opts and shallow_copy(opts) or shallow_copy(default_opts)\n  opts.verbose = true  -- safe: mutates a copy, not the shared default\nend\n",[32,1227,1228,1233,1244,1261,1266,1271,1299,1306,1310,1323,1334,1338,1343,1373,1385,1403,1419,1424,1428,1436,1446,1450,1455,1466,1489,1502],{"__ignoreMap":50},[54,1229,1230],{"class":56,"line":57},[54,1231,1232],{"class":60},"-- BAD: default table is shared across all calls — mutations persist!\n",[54,1234,1235,1237,1239,1242],{"class":56,"line":64},[54,1236,87],{"class":86},[54,1238,600],{"class":86},[54,1240,1241],{"class":127}," process",[54,1243,658],{"class":90},[54,1245,1246,1249,1251,1253,1255,1258],{"class":56,"line":70},[54,1247,1248],{"class":90},"  data ",[54,1250,94],{"class":86},[54,1252,639],{"class":90},[54,1254,1006],{"class":86},[54,1256,1257],{"class":90}," {}  ",[54,1259,1260],{"class":60},"-- if nil, uses the SAME {} every call? NO — Lua creates fresh {} per call\n",[54,1262,1263],{"class":56,"line":76},[54,1264,1265],{"class":60},"  -- Actually this is safe in Lua! Unlike Python's mutable default args, Lua's\n",[54,1267,1268],{"class":56,"line":83},[54,1269,1270],{"class":60},"  -- `or {}` evaluates the {} constructor fresh each call. This is fine.\n",[54,1272,1273,1276,1279,1281,1284,1286,1289,1291,1293,1296],{"class":56,"line":121},[54,1274,1275],{"class":90},"  data.",[54,1277,1278],{"class":127},"count",[54,1280,131],{"class":86},[54,1282,1283],{"class":90}," (data.",[54,1285,1278],{"class":127},[54,1287,1288],{"class":86}," or",[54,1290,466],{"class":100},[54,1292,969],{"class":90},[54,1294,1295],{"class":86},"+",[54,1297,1298],{"class":100}," 1\n",[54,1300,1301,1303],{"class":56,"line":141},[54,1302,852],{"class":86},[54,1304,1305],{"class":90}," data\n",[54,1307,1308],{"class":56,"line":161},[54,1309,422],{"class":86},[54,1311,1312,1315,1318,1320],{"class":56,"line":179},[54,1313,1314],{"class":100},"process",[54,1316,1317],{"class":90},"().",[54,1319,1278],{"class":127},[54,1321,1322],{"class":60},"  -- 1\n",[54,1324,1325,1327,1329,1331],{"class":56,"line":191},[54,1326,1314],{"class":100},[54,1328,1317],{"class":90},[54,1330,1278],{"class":127},[54,1332,1333],{"class":60},"  -- 1 (fresh table each call — safe)\n",[54,1335,1336],{"class":56,"line":196},[54,1337,80],{"emptyLinePlaceholder":79},[54,1339,1340],{"class":56,"line":202},[54,1341,1342],{"class":60},"-- The REAL trap: default table stored in an upvalue (shared)\n",[54,1344,1345,1347,1350,1352,1355,1357,1360,1363,1365,1368,1370],{"class":56,"line":215},[54,1346,87],{"class":86},[54,1348,1349],{"class":90}," default_opts ",[54,1351,94],{"class":86},[54,1353,1354],{"class":90}," {verbose ",[54,1356,94],{"class":86},[54,1358,1359],{"class":100}," false",[54,1361,1362],{"class":90},", timeout ",[54,1364,94],{"class":86},[54,1366,1367],{"class":100}," 5000",[54,1369,322],{"class":90},[54,1371,1372],{"class":60},"-- shared object!\n",[54,1374,1375,1377,1379,1382],{"class":56,"line":232},[54,1376,87],{"class":86},[54,1378,600],{"class":86},[54,1380,1381],{"class":127}," process2",[54,1383,1384],{"class":90},"(opts)\n",[54,1386,1387,1390,1392,1395,1397,1400],{"class":56,"line":249},[54,1388,1389],{"class":90},"  opts ",[54,1391,94],{"class":86},[54,1393,1394],{"class":90}," opts ",[54,1396,1006],{"class":86},[54,1398,1399],{"class":90}," default_opts  ",[54,1401,1402],{"class":60},"-- if caller passes nothing, uses SHARED default_opts\n",[54,1404,1405,1408,1411,1413,1416],{"class":56,"line":270},[54,1406,1407],{"class":90},"  opts.",[54,1409,1410],{"class":127},"verbose",[54,1412,131],{"class":86},[54,1414,1415],{"class":100}," true",[54,1417,1418],{"class":60},"  -- MUTATES the shared default!\n",[54,1420,1421],{"class":56,"line":276},[54,1422,1423],{"class":60},"  -- Next call with no args: opts.verbose is NOW true (leaked state)\n",[54,1425,1426],{"class":56,"line":281},[54,1427,422],{"class":86},[54,1429,1430,1433],{"class":56,"line":287},[54,1431,1432],{"class":100},"process2",[54,1434,1435],{"class":90},"()\n",[54,1437,1438,1440,1443],{"class":56,"line":293},[54,1439,1432],{"class":100},[54,1441,1442],{"class":90},"()  ",[54,1444,1445],{"class":60},"-- default_opts.verbose is now true — BUG\n",[54,1447,1448],{"class":56,"line":328},[54,1449,80],{"emptyLinePlaceholder":79},[54,1451,1452],{"class":56,"line":1059},[54,1453,1454],{"class":60},"-- FIX: copy the defaults, don't share the reference\n",[54,1456,1457,1459,1461,1464],{"class":56,"line":1070},[54,1458,87],{"class":86},[54,1460,600],{"class":86},[54,1462,1463],{"class":127}," process3",[54,1465,1384],{"class":90},[54,1467,1468,1470,1472,1474,1477,1479,1482,1484,1486],{"class":56,"line":1084},[54,1469,1389],{"class":90},[54,1471,94],{"class":86},[54,1473,1394],{"class":90},[54,1475,1476],{"class":86},"and",[54,1478,795],{"class":100},[54,1480,1481],{"class":90},"(opts) ",[54,1483,1006],{"class":86},[54,1485,795],{"class":100},[54,1487,1488],{"class":90},"(default_opts)\n",[54,1490,1491,1493,1495,1497,1499],{"class":56,"line":1099},[54,1492,1407],{"class":90},[54,1494,1410],{"class":127},[54,1496,131],{"class":86},[54,1498,1415],{"class":100},[54,1500,1501],{"class":60},"  -- safe: mutates a copy, not the shared default\n",[54,1503,1504],{"class":56,"line":1121},[54,1505,422],{"class":86},[37,1507,1509],{"id":1508},"oop-classes-via-metatables","OOP: Classes via Metatables",[42,1511,1512,1806,1813],{"language":44},[46,1513,1515],{"className":48,"code":1514,"language":44,"meta":50,"style":50},"-- Class pattern: metatable as the class, __index = self for method lookup\nlocal Animal = {}\nAnimal.__index = Animal  -- instances inherit methods from Animal table\n\nfunction Animal.new(name, sound)\n  -- setmetatable creates the instance; __index routes unknown lookups to Animal\n  local self = setmetatable({}, Animal)\n  self.name = name\n  self.sound = sound\n  return self\nend\n\nfunction Animal:speak()\n  return self.name .. \" says \" .. self.sound\nend\n\nfunction Animal:rename(new_name)\n  self.name = new_name\n  return self\nend\n\nlocal cat = Animal.new(\"Whiskers\", \"meow\")\nprint(cat:speak())  -- \"Whiskers says meow\"\n-- cat:speak() → cat.speak → not in instance → __index → Animal.speak → call with self=cat\n\n-- Method call syntax: `:` passes self automatically, `.` does not\ncat:speak()       -- self = cat (implicit)\ncat.speak(cat)    -- explicit self (same thing)\n",[32,1516,1517,1522,1533,1548,1552,1568,1573,1587,1601,1615,1622,1626,1630,1644,1670,1674,1678,1692,1705,1711,1715,1719,1746,1765,1770,1774,1779,1793],{"__ignoreMap":50},[54,1518,1519],{"class":56,"line":57},[54,1520,1521],{"class":60},"-- Class pattern: metatable as the class, __index = self for method lookup\n",[54,1523,1524,1526,1529,1531],{"class":56,"line":64},[54,1525,87],{"class":86},[54,1527,1528],{"class":90}," Animal ",[54,1530,94],{"class":86},[54,1532,383],{"class":90},[54,1534,1535,1538,1540,1542,1545],{"class":56,"line":70},[54,1536,1537],{"class":90},"Animal.",[54,1539,34],{"class":127},[54,1541,131],{"class":86},[54,1543,1544],{"class":90}," Animal  ",[54,1546,1547],{"class":60},"-- instances inherit methods from Animal table\n",[54,1549,1550],{"class":56,"line":76},[54,1551,80],{"emptyLinePlaceholder":79},[54,1553,1554,1557,1560,1562,1565],{"class":56,"line":83},[54,1555,1556],{"class":86},"function",[54,1558,1559],{"class":127}," Animal",[54,1561,931],{"class":90},[54,1563,1564],{"class":127},"new",[54,1566,1567],{"class":90},"(name, sound)\n",[54,1569,1570],{"class":56,"line":121},[54,1571,1572],{"class":60},"  -- setmetatable creates the instance; __index routes unknown lookups to Animal\n",[54,1574,1575,1577,1580,1582,1584],{"class":56,"line":141},[54,1576,802],{"class":86},[54,1578,1579],{"class":100}," self",[54,1581,131],{"class":86},[54,1583,1131],{"class":100},[54,1585,1586],{"class":90},"({}, Animal)\n",[54,1588,1589,1592,1594,1596,1598],{"class":56,"line":161},[54,1590,1591],{"class":100},"  self",[54,1593,931],{"class":90},[54,1595,128],{"class":127},[54,1597,131],{"class":86},[54,1599,1600],{"class":90}," name\n",[54,1602,1603,1605,1607,1610,1612],{"class":56,"line":179},[54,1604,1591],{"class":100},[54,1606,931],{"class":90},[54,1608,1609],{"class":127},"sound",[54,1611,131],{"class":86},[54,1613,1614],{"class":90}," sound\n",[54,1616,1617,1619],{"class":56,"line":191},[54,1618,852],{"class":86},[54,1620,1621],{"class":100}," self\n",[54,1623,1624],{"class":56,"line":196},[54,1625,422],{"class":86},[54,1627,1628],{"class":56,"line":202},[54,1629,80],{"emptyLinePlaceholder":79},[54,1631,1632,1634,1636,1639,1642],{"class":56,"line":215},[54,1633,1556],{"class":86},[54,1635,1559],{"class":127},[54,1637,1638],{"class":90},":",[54,1640,1641],{"class":127},"speak",[54,1643,1435],{"class":90},[54,1645,1646,1648,1650,1652,1654,1657,1660,1663,1665,1667],{"class":56,"line":232},[54,1647,852],{"class":86},[54,1649,1579],{"class":100},[54,1651,931],{"class":90},[54,1653,128],{"class":127},[54,1655,1656],{"class":86}," ..",[54,1658,1659],{"class":134}," \" says \" ",[54,1661,1662],{"class":86},"..",[54,1664,1579],{"class":100},[54,1666,931],{"class":90},[54,1668,1669],{"class":127},"sound\n",[54,1671,1672],{"class":56,"line":249},[54,1673,422],{"class":86},[54,1675,1676],{"class":56,"line":270},[54,1677,80],{"emptyLinePlaceholder":79},[54,1679,1680,1682,1684,1686,1689],{"class":56,"line":276},[54,1681,1556],{"class":86},[54,1683,1559],{"class":127},[54,1685,1638],{"class":90},[54,1687,1688],{"class":127},"rename",[54,1690,1691],{"class":90},"(new_name)\n",[54,1693,1694,1696,1698,1700,1702],{"class":56,"line":281},[54,1695,1591],{"class":100},[54,1697,931],{"class":90},[54,1699,128],{"class":127},[54,1701,131],{"class":86},[54,1703,1704],{"class":90}," new_name\n",[54,1706,1707,1709],{"class":56,"line":287},[54,1708,852],{"class":86},[54,1710,1621],{"class":100},[54,1712,1713],{"class":56,"line":293},[54,1714,422],{"class":86},[54,1716,1717],{"class":56,"line":328},[54,1718,80],{"emptyLinePlaceholder":79},[54,1720,1721,1723,1726,1728,1731,1733,1735,1738,1740,1743],{"class":56,"line":1059},[54,1722,87],{"class":86},[54,1724,1725],{"class":90}," cat ",[54,1727,94],{"class":86},[54,1729,1730],{"class":90}," Animal.",[54,1732,1564],{"class":100},[54,1734,492],{"class":90},[54,1736,1737],{"class":134},"\"Whiskers\"",[54,1739,104],{"class":90},[54,1741,1742],{"class":134},"\"meow\"",[54,1744,1745],{"class":90},")\n",[54,1747,1748,1750,1752,1755,1757,1759,1762],{"class":56,"line":1070},[54,1749,573],{"class":100},[54,1751,492],{"class":90},[54,1753,1754],{"class":127},"cat",[54,1756,1638],{"class":90},[54,1758,1641],{"class":100},[54,1760,1761],{"class":90},"())  ",[54,1763,1764],{"class":60},"-- \"Whiskers says meow\"\n",[54,1766,1767],{"class":56,"line":1084},[54,1768,1769],{"class":60},"-- cat:speak() → cat.speak → not in instance → __index → Animal.speak → call with self=cat\n",[54,1771,1772],{"class":56,"line":1099},[54,1773,80],{"emptyLinePlaceholder":79},[54,1775,1776],{"class":56,"line":1121},[54,1777,1778],{"class":60},"-- Method call syntax: `:` passes self automatically, `.` does not\n",[54,1780,1781,1783,1785,1787,1790],{"class":56,"line":1126},[54,1782,1754],{"class":127},[54,1784,1638],{"class":90},[54,1786,1641],{"class":100},[54,1788,1789],{"class":90},"()       ",[54,1791,1792],{"class":60},"-- self = cat (implicit)\n",[54,1794,1795,1798,1800,1803],{"class":56,"line":1146},[54,1796,1797],{"class":90},"cat.",[54,1799,1641],{"class":100},[54,1801,1802],{"class":90},"(cat)    ",[54,1804,1805],{"class":60},"-- explicit self (same thing)\n",[37,1807,1809,1810,1812],{"id":1808},"inheritance-via-__index-chain","Inheritance via ",[32,1811,34],{}," Chain",[42,1814,1815,2306,2310],{"language":44},[46,1816,1818],{"className":48,"code":1817,"language":44,"meta":50,"style":50},"-- Single inheritance: derived class's __index points to base class\nlocal Dog = setmetatable({}, {__index = Animal})  -- Dog inherits from Animal\nDog.__index = Dog  -- Dog instances inherit from Dog (which inherits from Animal)\n\nfunction Dog.new(name, breed)\n  local self = Animal.new(name, \"woof\")  -- call base constructor\n  self.breed = breed\n  return setmetatable(self, Dog)  -- override metatable to Dog\nend\n\nfunction Dog:fetch()\n  return self.name .. \" fetches the ball\"\nend\n\n-- Override base method\nfunction Dog:speak()\n  return self.name .. \" barks loudly!\"\nend\n\nlocal buddy = Dog.new(\"Buddy\", \"Labrador\")\nprint(buddy:speak())  -- \"Buddy barks loudly!\" (Dog's override)\nprint(buddy:fetch())  -- \"Buddy fetches the ball\" (Dog's method)\nprint(buddy:rename(\"Doge\"):speak())  -- \"Doge barks loudly!\" (inherited from Animal)\n-- Method lookup chain: buddy → Dog (speak found here) → stop\n-- Method lookup chain: buddy → Dog (rename not found) → Animal (found here)\n\n-- Multi-level inheritance: A → B → C via chained __index\nlocal Puppy = setmetatable({}, {__index = Dog})\nPuppy.__index = Puppy\nfunction Puppy.new(name, breed)\n  local self = Dog.new(name, breed)\n  self.age = 0\n  return setmetatable(self, Puppy)\nend\nfunction Puppy:growth_year()\n  self.age = self.age + 1\n  return self\nend\nlocal pup = Puppy.new(\"Rex\", \"Poodle\")\nprint(pup:speak())  -- \"Rex barks loudly!\" (inherited from Dog via chain)\n",[32,1819,1820,1825,1847,1862,1866,1880,1903,1917,1933,1937,1941,1954,1969,1973,1977,1982,1994,2009,2013,2017,2043,2061,2078,2105,2110,2115,2119,2124,2142,2154,2167,2181,2195,2208,2213,2227,2248,2255,2260,2287],{"__ignoreMap":50},[54,1821,1822],{"class":56,"line":57},[54,1823,1824],{"class":60},"-- Single inheritance: derived class's __index points to base class\n",[54,1826,1827,1829,1832,1834,1836,1839,1841,1844],{"class":56,"line":64},[54,1828,87],{"class":86},[54,1830,1831],{"class":90}," Dog ",[54,1833,94],{"class":86},[54,1835,1131],{"class":100},[54,1837,1838],{"class":90},"({}, {__index ",[54,1840,94],{"class":86},[54,1842,1843],{"class":90}," Animal})  ",[54,1845,1846],{"class":60},"-- Dog inherits from Animal\n",[54,1848,1849,1852,1854,1856,1859],{"class":56,"line":70},[54,1850,1851],{"class":90},"Dog.",[54,1853,34],{"class":127},[54,1855,131],{"class":86},[54,1857,1858],{"class":90}," Dog  ",[54,1860,1861],{"class":60},"-- Dog instances inherit from Dog (which inherits from Animal)\n",[54,1863,1864],{"class":56,"line":76},[54,1865,80],{"emptyLinePlaceholder":79},[54,1867,1868,1870,1873,1875,1877],{"class":56,"line":83},[54,1869,1556],{"class":86},[54,1871,1872],{"class":127}," Dog",[54,1874,931],{"class":90},[54,1876,1564],{"class":127},[54,1878,1879],{"class":90},"(name, breed)\n",[54,1881,1882,1884,1886,1888,1890,1892,1895,1898,1900],{"class":56,"line":121},[54,1883,802],{"class":86},[54,1885,1579],{"class":100},[54,1887,131],{"class":86},[54,1889,1730],{"class":90},[54,1891,1564],{"class":100},[54,1893,1894],{"class":90},"(name, ",[54,1896,1897],{"class":134},"\"woof\"",[54,1899,767],{"class":90},[54,1901,1902],{"class":60},"-- call base constructor\n",[54,1904,1905,1907,1909,1912,1914],{"class":56,"line":141},[54,1906,1591],{"class":100},[54,1908,931],{"class":90},[54,1910,1911],{"class":127},"breed",[54,1913,131],{"class":86},[54,1915,1916],{"class":90}," breed\n",[54,1918,1919,1921,1923,1925,1927,1930],{"class":56,"line":161},[54,1920,852],{"class":86},[54,1922,1131],{"class":100},[54,1924,492],{"class":90},[54,1926,1174],{"class":100},[54,1928,1929],{"class":90},", Dog)  ",[54,1931,1932],{"class":60},"-- override metatable to Dog\n",[54,1934,1935],{"class":56,"line":179},[54,1936,422],{"class":86},[54,1938,1939],{"class":56,"line":191},[54,1940,80],{"emptyLinePlaceholder":79},[54,1942,1943,1945,1947,1949,1952],{"class":56,"line":196},[54,1944,1556],{"class":86},[54,1946,1872],{"class":127},[54,1948,1638],{"class":90},[54,1950,1951],{"class":127},"fetch",[54,1953,1435],{"class":90},[54,1955,1956,1958,1960,1962,1964,1966],{"class":56,"line":202},[54,1957,852],{"class":86},[54,1959,1579],{"class":100},[54,1961,931],{"class":90},[54,1963,128],{"class":127},[54,1965,1656],{"class":86},[54,1967,1968],{"class":134}," \" fetches the ball\"\n",[54,1970,1971],{"class":56,"line":215},[54,1972,422],{"class":86},[54,1974,1975],{"class":56,"line":232},[54,1976,80],{"emptyLinePlaceholder":79},[54,1978,1979],{"class":56,"line":249},[54,1980,1981],{"class":60},"-- Override base method\n",[54,1983,1984,1986,1988,1990,1992],{"class":56,"line":270},[54,1985,1556],{"class":86},[54,1987,1872],{"class":127},[54,1989,1638],{"class":90},[54,1991,1641],{"class":127},[54,1993,1435],{"class":90},[54,1995,1996,1998,2000,2002,2004,2006],{"class":56,"line":276},[54,1997,852],{"class":86},[54,1999,1579],{"class":100},[54,2001,931],{"class":90},[54,2003,128],{"class":127},[54,2005,1656],{"class":86},[54,2007,2008],{"class":134}," \" barks loudly!\"\n",[54,2010,2011],{"class":56,"line":281},[54,2012,422],{"class":86},[54,2014,2015],{"class":56,"line":287},[54,2016,80],{"emptyLinePlaceholder":79},[54,2018,2019,2021,2024,2026,2029,2031,2033,2036,2038,2041],{"class":56,"line":293},[54,2020,87],{"class":86},[54,2022,2023],{"class":90}," buddy ",[54,2025,94],{"class":86},[54,2027,2028],{"class":90}," Dog.",[54,2030,1564],{"class":100},[54,2032,492],{"class":90},[54,2034,2035],{"class":134},"\"Buddy\"",[54,2037,104],{"class":90},[54,2039,2040],{"class":134},"\"Labrador\"",[54,2042,1745],{"class":90},[54,2044,2045,2047,2049,2052,2054,2056,2058],{"class":56,"line":328},[54,2046,573],{"class":100},[54,2048,492],{"class":90},[54,2050,2051],{"class":127},"buddy",[54,2053,1638],{"class":90},[54,2055,1641],{"class":100},[54,2057,1761],{"class":90},[54,2059,2060],{"class":60},"-- \"Buddy barks loudly!\" (Dog's override)\n",[54,2062,2063,2065,2067,2069,2071,2073,2075],{"class":56,"line":1059},[54,2064,573],{"class":100},[54,2066,492],{"class":90},[54,2068,2051],{"class":127},[54,2070,1638],{"class":90},[54,2072,1951],{"class":100},[54,2074,1761],{"class":90},[54,2076,2077],{"class":60},"-- \"Buddy fetches the ball\" (Dog's method)\n",[54,2079,2080,2082,2084,2086,2088,2090,2092,2095,2098,2100,2102],{"class":56,"line":1070},[54,2081,573],{"class":100},[54,2083,492],{"class":90},[54,2085,2051],{"class":127},[54,2087,1638],{"class":90},[54,2089,1688],{"class":100},[54,2091,492],{"class":90},[54,2093,2094],{"class":134},"\"Doge\"",[54,2096,2097],{"class":90},"):",[54,2099,1641],{"class":100},[54,2101,1761],{"class":90},[54,2103,2104],{"class":60},"-- \"Doge barks loudly!\" (inherited from Animal)\n",[54,2106,2107],{"class":56,"line":1084},[54,2108,2109],{"class":60},"-- Method lookup chain: buddy → Dog (speak found here) → stop\n",[54,2111,2112],{"class":56,"line":1099},[54,2113,2114],{"class":60},"-- Method lookup chain: buddy → Dog (rename not found) → Animal (found here)\n",[54,2116,2117],{"class":56,"line":1121},[54,2118,80],{"emptyLinePlaceholder":79},[54,2120,2121],{"class":56,"line":1126},[54,2122,2123],{"class":60},"-- Multi-level inheritance: A → B → C via chained __index\n",[54,2125,2126,2128,2131,2133,2135,2137,2139],{"class":56,"line":1146},[54,2127,87],{"class":86},[54,2129,2130],{"class":90}," Puppy ",[54,2132,94],{"class":86},[54,2134,1131],{"class":100},[54,2136,1838],{"class":90},[54,2138,94],{"class":86},[54,2140,2141],{"class":90}," Dog})\n",[54,2143,2144,2147,2149,2151],{"class":56,"line":1151},[54,2145,2146],{"class":90},"Puppy.",[54,2148,34],{"class":127},[54,2150,131],{"class":86},[54,2152,2153],{"class":90}," Puppy\n",[54,2155,2156,2158,2161,2163,2165],{"class":56,"line":1156},[54,2157,1556],{"class":86},[54,2159,2160],{"class":127}," Puppy",[54,2162,931],{"class":90},[54,2164,1564],{"class":127},[54,2166,1879],{"class":90},[54,2168,2169,2171,2173,2175,2177,2179],{"class":56,"line":1168},[54,2170,802],{"class":86},[54,2172,1579],{"class":100},[54,2174,131],{"class":86},[54,2176,2028],{"class":90},[54,2178,1564],{"class":100},[54,2180,1879],{"class":90},[54,2182,2183,2185,2187,2190,2192],{"class":56,"line":1185},[54,2184,1591],{"class":100},[54,2186,931],{"class":90},[54,2188,2189],{"class":127},"age",[54,2191,131],{"class":86},[54,2193,2194],{"class":100}," 0\n",[54,2196,2197,2199,2201,2203,2205],{"class":56,"line":1200},[54,2198,852],{"class":86},[54,2200,1131],{"class":100},[54,2202,492],{"class":90},[54,2204,1174],{"class":100},[54,2206,2207],{"class":90},", Puppy)\n",[54,2209,2211],{"class":56,"line":2210},34,[54,2212,422],{"class":86},[54,2214,2216,2218,2220,2222,2225],{"class":56,"line":2215},35,[54,2217,1556],{"class":86},[54,2219,2160],{"class":127},[54,2221,1638],{"class":90},[54,2223,2224],{"class":127},"growth_year",[54,2226,1435],{"class":90},[54,2228,2230,2232,2234,2236,2238,2240,2242,2244,2246],{"class":56,"line":2229},36,[54,2231,1591],{"class":100},[54,2233,931],{"class":90},[54,2235,2189],{"class":127},[54,2237,131],{"class":86},[54,2239,1579],{"class":100},[54,2241,931],{"class":90},[54,2243,2189],{"class":127},[54,2245,623],{"class":86},[54,2247,1298],{"class":100},[54,2249,2251,2253],{"class":56,"line":2250},37,[54,2252,852],{"class":86},[54,2254,1621],{"class":100},[54,2256,2258],{"class":56,"line":2257},38,[54,2259,422],{"class":86},[54,2261,2263,2265,2268,2270,2273,2275,2277,2280,2282,2285],{"class":56,"line":2262},39,[54,2264,87],{"class":86},[54,2266,2267],{"class":90}," pup ",[54,2269,94],{"class":86},[54,2271,2272],{"class":90}," Puppy.",[54,2274,1564],{"class":100},[54,2276,492],{"class":90},[54,2278,2279],{"class":134},"\"Rex\"",[54,2281,104],{"class":90},[54,2283,2284],{"class":134},"\"Poodle\"",[54,2286,1745],{"class":90},[54,2288,2290,2292,2294,2297,2299,2301,2303],{"class":56,"line":2289},40,[54,2291,573],{"class":100},[54,2293,492],{"class":90},[54,2295,2296],{"class":127},"pup",[54,2298,1638],{"class":90},[54,2300,1641],{"class":100},[54,2302,1761],{"class":90},[54,2304,2305],{"class":60},"-- \"Rex barks loudly!\" (inherited from Dog via chain)\n",[37,2307,2309],{"id":2308},"mixins-multiple-inheritance-alternative","Mixins: Multiple Inheritance Alternative",[42,2311,2312,2920,2924,2928],{"language":44},[46,2313,2315],{"className":48,"code":2314,"language":44,"meta":50,"style":50},"-- Lua has no multiple inheritance. Mixins: copy methods from multiple tables into one class.\nlocal function mixin(target, ...)\n  for _, source in ipairs({...}) do\n    for k, v in pairs(source) do\n      if k ~= \"__index\" and type(v) == \"function\" then\n        target[k] = v  -- copy method references\n      end\n    end\n  end\nend\n\n-- Define capabilities as independent tables\nlocal Observable = {}\nfunction Observable:on(event, fn)\n  self._listeners = self._listeners or {}\n  self._listeners[event] = self._listeners[event] or {}\n  table.insert(self._listeners[event], fn)\n  return self\nend\nfunction Observable:emit(event, ...)\n  for _, fn in ipairs(self._listeners and self._listeners[event] or {}) do\n    fn(...)\n  end\nend\n\nlocal Serializable = {}\nfunction Serializable:serialize()\n  local t = {}\n  for k, v in pairs(self) do\n    if type(k) == \"string\" and not k:match(\"^_\") then\n      t[k] = v\n    end\n  end\n  return t\nend\n\n-- Compose: a class with multiple capabilities\nlocal EventEmitter = {}\nEventEmitter.__index = EventEmitter\nmixin(EventEmitter, Observable, Serializable)\n\nfunction EventEmitter.new(id)\n  return setmetatable({id = id}, EventEmitter)\nend\n\nlocal emitter = EventEmitter.new(\"e1\")\nemitter:on(\"data\", function(x) print(\"got:\", x) end)\nemitter:emit(\"data\", 42)  -- \"got: 42\"\nprint(emitter:serialize().id)  -- \"e1\"\n",[32,2316,2317,2322,2334,2357,2373,2401,2413,2418,2423,2427,2431,2435,2440,2451,2466,2487,2512,2528,2534,2538,2552,2589,2600,2604,2608,2612,2623,2637,2647,2665,2702,2712,2716,2720,2727,2731,2735,2740,2751,2763,2771,2776,2791,2806,2811,2816,2838,2874,2897],{"__ignoreMap":50},[54,2318,2319],{"class":56,"line":57},[54,2320,2321],{"class":60},"-- Lua has no multiple inheritance. Mixins: copy methods from multiple tables into one class.\n",[54,2323,2324,2326,2328,2331],{"class":56,"line":64},[54,2325,87],{"class":86},[54,2327,600],{"class":86},[54,2329,2330],{"class":127}," mixin",[54,2332,2333],{"class":90},"(target, ...)\n",[54,2335,2336,2338,2341,2343,2346,2349,2352,2355],{"class":56,"line":70},[54,2337,814],{"class":86},[54,2339,2340],{"class":90}," _, source ",[54,2342,820],{"class":86},[54,2344,2345],{"class":100}," ipairs",[54,2347,2348],{"class":90},"({",[54,2350,2351],{"class":100},"...",[54,2353,2354],{"class":90},"}) ",[54,2356,829],{"class":86},[54,2358,2359,2362,2364,2366,2368,2371],{"class":56,"line":76},[54,2360,2361],{"class":86},"    for",[54,2363,817],{"class":90},[54,2365,820],{"class":86},[54,2367,823],{"class":100},[54,2369,2370],{"class":90},"(source) ",[54,2372,829],{"class":86},[54,2374,2375,2378,2381,2383,2386,2388,2390,2393,2395,2398],{"class":56,"line":83},[54,2376,2377],{"class":86},"      if",[54,2379,2380],{"class":90}," k ",[54,2382,1042],{"class":86},[54,2384,2385],{"class":134}," \"__index\" ",[54,2387,1476],{"class":86},[54,2389,1037],{"class":100},[54,2391,2392],{"class":90},"(v) ",[54,2394,721],{"class":86},[54,2396,2397],{"class":134}," \"function\" ",[54,2399,2400],{"class":86},"then\n",[54,2402,2403,2406,2408,2410],{"class":56,"line":121},[54,2404,2405],{"class":90},"        target[k] ",[54,2407,94],{"class":86},[54,2409,839],{"class":90},[54,2411,2412],{"class":60},"-- copy method references\n",[54,2414,2415],{"class":56,"line":141},[54,2416,2417],{"class":86},"      end\n",[54,2419,2420],{"class":56,"line":161},[54,2421,2422],{"class":86},"    end\n",[54,2424,2425],{"class":56,"line":179},[54,2426,847],{"class":86},[54,2428,2429],{"class":56,"line":191},[54,2430,422],{"class":86},[54,2432,2433],{"class":56,"line":196},[54,2434,80],{"emptyLinePlaceholder":79},[54,2436,2437],{"class":56,"line":202},[54,2438,2439],{"class":60},"-- Define capabilities as independent tables\n",[54,2441,2442,2444,2447,2449],{"class":56,"line":215},[54,2443,87],{"class":86},[54,2445,2446],{"class":90}," Observable ",[54,2448,94],{"class":86},[54,2450,383],{"class":90},[54,2452,2453,2455,2458,2460,2463],{"class":56,"line":232},[54,2454,1556],{"class":86},[54,2456,2457],{"class":127}," Observable",[54,2459,1638],{"class":90},[54,2461,2462],{"class":127},"on",[54,2464,2465],{"class":90},"(event, fn)\n",[54,2467,2468,2470,2472,2475,2477,2479,2481,2483,2485],{"class":56,"line":249},[54,2469,1591],{"class":100},[54,2471,931],{"class":90},[54,2473,2474],{"class":127},"_listeners",[54,2476,131],{"class":86},[54,2478,1579],{"class":100},[54,2480,931],{"class":90},[54,2482,2474],{"class":127},[54,2484,1288],{"class":86},[54,2486,383],{"class":90},[54,2488,2489,2491,2493,2495,2498,2500,2502,2504,2506,2508,2510],{"class":56,"line":270},[54,2490,1591],{"class":100},[54,2492,931],{"class":90},[54,2494,2474],{"class":127},[54,2496,2497],{"class":90},"[event] ",[54,2499,94],{"class":86},[54,2501,1579],{"class":100},[54,2503,931],{"class":90},[54,2505,2474],{"class":127},[54,2507,2497],{"class":90},[54,2509,1006],{"class":86},[54,2511,383],{"class":90},[54,2513,2514,2517,2519,2521,2523,2525],{"class":56,"line":276},[54,2515,2516],{"class":100},"  table.insert",[54,2518,492],{"class":90},[54,2520,1174],{"class":100},[54,2522,931],{"class":90},[54,2524,2474],{"class":127},[54,2526,2527],{"class":90},"[event], fn)\n",[54,2529,2530,2532],{"class":56,"line":281},[54,2531,852],{"class":86},[54,2533,1621],{"class":100},[54,2535,2536],{"class":56,"line":287},[54,2537,422],{"class":86},[54,2539,2540,2542,2544,2546,2549],{"class":56,"line":293},[54,2541,1556],{"class":86},[54,2543,2457],{"class":127},[54,2545,1638],{"class":90},[54,2547,2548],{"class":127},"emit",[54,2550,2551],{"class":90},"(event, ...)\n",[54,2553,2554,2556,2559,2561,2563,2565,2567,2569,2571,2574,2576,2578,2580,2582,2584,2587],{"class":56,"line":328},[54,2555,814],{"class":86},[54,2557,2558],{"class":90}," _, fn ",[54,2560,820],{"class":86},[54,2562,2345],{"class":100},[54,2564,492],{"class":90},[54,2566,1174],{"class":100},[54,2568,931],{"class":90},[54,2570,2474],{"class":127},[54,2572,2573],{"class":86}," and",[54,2575,1579],{"class":100},[54,2577,931],{"class":90},[54,2579,2474],{"class":127},[54,2581,2497],{"class":90},[54,2583,1006],{"class":86},[54,2585,2586],{"class":90}," {}) ",[54,2588,829],{"class":86},[54,2590,2591,2594,2596,2598],{"class":56,"line":1059},[54,2592,2593],{"class":100},"    fn",[54,2595,492],{"class":90},[54,2597,2351],{"class":100},[54,2599,1745],{"class":90},[54,2601,2602],{"class":56,"line":1070},[54,2603,847],{"class":86},[54,2605,2606],{"class":56,"line":1084},[54,2607,422],{"class":86},[54,2609,2610],{"class":56,"line":1099},[54,2611,80],{"emptyLinePlaceholder":79},[54,2613,2614,2616,2619,2621],{"class":56,"line":1121},[54,2615,87],{"class":86},[54,2617,2618],{"class":90}," Serializable ",[54,2620,94],{"class":86},[54,2622,383],{"class":90},[54,2624,2625,2627,2630,2632,2635],{"class":56,"line":1126},[54,2626,1556],{"class":86},[54,2628,2629],{"class":127}," Serializable",[54,2631,1638],{"class":90},[54,2633,2634],{"class":127},"serialize",[54,2636,1435],{"class":90},[54,2638,2639,2641,2643,2645],{"class":56,"line":1146},[54,2640,802],{"class":86},[54,2642,91],{"class":90},[54,2644,94],{"class":86},[54,2646,383],{"class":90},[54,2648,2649,2651,2653,2655,2657,2659,2661,2663],{"class":56,"line":1151},[54,2650,814],{"class":86},[54,2652,817],{"class":90},[54,2654,820],{"class":86},[54,2656,823],{"class":100},[54,2658,492],{"class":90},[54,2660,1174],{"class":100},[54,2662,969],{"class":90},[54,2664,829],{"class":86},[54,2666,2667,2670,2672,2675,2677,2680,2682,2685,2688,2690,2693,2695,2698,2700],{"class":56,"line":1156},[54,2668,2669],{"class":86},"    if",[54,2671,1037],{"class":100},[54,2673,2674],{"class":90},"(k) ",[54,2676,721],{"class":86},[54,2678,2679],{"class":134}," \"string\" ",[54,2681,1476],{"class":86},[54,2683,2684],{"class":86}," not",[54,2686,2687],{"class":127}," k",[54,2689,1638],{"class":90},[54,2691,2692],{"class":100},"match",[54,2694,492],{"class":90},[54,2696,2697],{"class":134},"\"^_\"",[54,2699,969],{"class":90},[54,2701,2400],{"class":86},[54,2703,2704,2707,2709],{"class":56,"line":1168},[54,2705,2706],{"class":90},"      t[k] ",[54,2708,94],{"class":86},[54,2710,2711],{"class":90}," v\n",[54,2713,2714],{"class":56,"line":1185},[54,2715,2422],{"class":86},[54,2717,2718],{"class":56,"line":1200},[54,2719,847],{"class":86},[54,2721,2722,2724],{"class":56,"line":2210},[54,2723,852],{"class":86},[54,2725,2726],{"class":90}," t\n",[54,2728,2729],{"class":56,"line":2215},[54,2730,422],{"class":86},[54,2732,2733],{"class":56,"line":2229},[54,2734,80],{"emptyLinePlaceholder":79},[54,2736,2737],{"class":56,"line":2250},[54,2738,2739],{"class":60},"-- Compose: a class with multiple capabilities\n",[54,2741,2742,2744,2747,2749],{"class":56,"line":2257},[54,2743,87],{"class":86},[54,2745,2746],{"class":90}," EventEmitter ",[54,2748,94],{"class":86},[54,2750,383],{"class":90},[54,2752,2753,2756,2758,2760],{"class":56,"line":2262},[54,2754,2755],{"class":90},"EventEmitter.",[54,2757,34],{"class":127},[54,2759,131],{"class":86},[54,2761,2762],{"class":90}," EventEmitter\n",[54,2764,2765,2768],{"class":56,"line":2289},[54,2766,2767],{"class":100},"mixin",[54,2769,2770],{"class":90},"(EventEmitter, Observable, Serializable)\n",[54,2772,2774],{"class":56,"line":2773},41,[54,2775,80],{"emptyLinePlaceholder":79},[54,2777,2779,2781,2784,2786,2788],{"class":56,"line":2778},42,[54,2780,1556],{"class":86},[54,2782,2783],{"class":127}," EventEmitter",[54,2785,931],{"class":90},[54,2787,1564],{"class":127},[54,2789,2790],{"class":90},"(id)\n",[54,2792,2794,2796,2798,2801,2803],{"class":56,"line":2793},43,[54,2795,852],{"class":86},[54,2797,1131],{"class":100},[54,2799,2800],{"class":90},"({id ",[54,2802,94],{"class":86},[54,2804,2805],{"class":90}," id}, EventEmitter)\n",[54,2807,2809],{"class":56,"line":2808},44,[54,2810,422],{"class":86},[54,2812,2814],{"class":56,"line":2813},45,[54,2815,80],{"emptyLinePlaceholder":79},[54,2817,2819,2821,2824,2826,2829,2831,2833,2836],{"class":56,"line":2818},46,[54,2820,87],{"class":86},[54,2822,2823],{"class":90}," emitter ",[54,2825,94],{"class":86},[54,2827,2828],{"class":90}," EventEmitter.",[54,2830,1564],{"class":100},[54,2832,492],{"class":90},[54,2834,2835],{"class":134},"\"e1\"",[54,2837,1745],{"class":90},[54,2839,2841,2844,2846,2848,2850,2853,2855,2857,2860,2862,2864,2867,2870,2872],{"class":56,"line":2840},47,[54,2842,2843],{"class":127},"emitter",[54,2845,1638],{"class":90},[54,2847,2462],{"class":100},[54,2849,492],{"class":90},[54,2851,2852],{"class":134},"\"data\"",[54,2854,104],{"class":90},[54,2856,1556],{"class":86},[54,2858,2859],{"class":90},"(x) ",[54,2861,573],{"class":100},[54,2863,492],{"class":90},[54,2865,2866],{"class":134},"\"got:\"",[54,2868,2869],{"class":90},", x) ",[54,2871,1027],{"class":86},[54,2873,1745],{"class":90},[54,2875,2877,2879,2881,2883,2885,2887,2889,2892,2894],{"class":56,"line":2876},48,[54,2878,2843],{"class":127},[54,2880,1638],{"class":90},[54,2882,2548],{"class":100},[54,2884,492],{"class":90},[54,2886,2852],{"class":134},[54,2888,104],{"class":90},[54,2890,2891],{"class":100},"42",[54,2893,767],{"class":90},[54,2895,2896],{"class":60},"-- \"got: 42\"\n",[54,2898,2900,2902,2904,2906,2908,2910,2912,2915,2917],{"class":56,"line":2899},49,[54,2901,573],{"class":100},[54,2903,492],{"class":90},[54,2905,2843],{"class":127},[54,2907,1638],{"class":90},[54,2909,2634],{"class":100},[54,2911,1317],{"class":90},[54,2913,2914],{"class":127},"id",[54,2916,767],{"class":90},[54,2918,2919],{"class":60},"-- \"e1\"\n",[37,2921,2923],{"id":2922},"production-data-structures","Production Data Structures",[338,2925,2927],{"id":2926},"linked-list-o1-prepend","Linked list (O(1) prepend)",[42,2929,2930,3614,3618],{"language":44},[46,2931,2933],{"className":48,"code":2932,"language":44,"meta":50,"style":50},"local List = {}\nList.__index = List\n\nfunction List.new()\n  return setmetatable({head = nil, tail = nil, size = 0}, List)\nend\n\nfunction List:push_front(v)  -- O(1)\n  self.head = {value = v, next = self.head}\n  if not self.tail then self.tail = self.head end\n  self.size = self.size + 1\n  return self\nend\n\nfunction List:push_back(v)  -- O(1) (with tail pointer)\n  local node = {value = v, next = nil}\n  if self.tail then\n    self.tail.next = node\n  else\n    self.head = node\n  end\n  self.tail = node\n  self.size = self.size + 1\n  return self\nend\n\nfunction List:pop_front()  -- O(1)\n  if not self.head then return nil end\n  local v = self.head.value\n  self.head = self.head.next\n  if not self.head then self.tail = nil end\n  self.size = self.size - 1\n  return v\nend\n\nfunction List:iter()  -- stateless iterator\n  local function walker(node) return node and node.value, node.next end\n  return coroutine.wrap(function()\n    local node = self.head\n    while node do\n      coroutine.yield(node.value)\n      node = node.next\n    end\n  end)\nend\n\nlocal list = List.new()\nlist:push_back(1):push_front(0):push_back(2)\nfor v in list:iter() do io.write(v, \" \") end  -- 0 1 2\n",[32,2934,2935,2946,2958,2962,2975,3006,3010,3014,3031,3060,3093,3114,3120,3124,3128,3144,3165,3178,3197,3202,3214,3218,3230,3250,3256,3260,3264,3279,3299,3319,3340,3366,3387,3393,3397,3401,3417,3449,3462,3478,3487,3499,3510,3514,3521,3525,3529,3545,3577],{"__ignoreMap":50},[54,2936,2937,2939,2942,2944],{"class":56,"line":57},[54,2938,87],{"class":86},[54,2940,2941],{"class":90}," List ",[54,2943,94],{"class":86},[54,2945,383],{"class":90},[54,2947,2948,2951,2953,2955],{"class":56,"line":64},[54,2949,2950],{"class":90},"List.",[54,2952,34],{"class":127},[54,2954,131],{"class":86},[54,2956,2957],{"class":90}," List\n",[54,2959,2960],{"class":56,"line":70},[54,2961,80],{"emptyLinePlaceholder":79},[54,2963,2964,2966,2969,2971,2973],{"class":56,"line":76},[54,2965,1556],{"class":86},[54,2967,2968],{"class":127}," List",[54,2970,931],{"class":90},[54,2972,1564],{"class":127},[54,2974,1435],{"class":90},[54,2976,2977,2979,2981,2984,2986,2989,2992,2994,2996,2999,3001,3003],{"class":56,"line":83},[54,2978,852],{"class":86},[54,2980,1131],{"class":100},[54,2982,2983],{"class":90},"({head ",[54,2985,94],{"class":86},[54,2987,2988],{"class":100}," nil",[54,2990,2991],{"class":90},", tail ",[54,2993,94],{"class":86},[54,2995,2988],{"class":100},[54,2997,2998],{"class":90},", size ",[54,3000,94],{"class":86},[54,3002,466],{"class":100},[54,3004,3005],{"class":90},"}, List)\n",[54,3007,3008],{"class":56,"line":121},[54,3009,422],{"class":86},[54,3011,3012],{"class":56,"line":141},[54,3013,80],{"emptyLinePlaceholder":79},[54,3015,3016,3018,3020,3022,3025,3028],{"class":56,"line":161},[54,3017,1556],{"class":86},[54,3019,2968],{"class":127},[54,3021,1638],{"class":90},[54,3023,3024],{"class":127},"push_front",[54,3026,3027],{"class":90},"(v)  ",[54,3029,3030],{"class":60},"-- O(1)\n",[54,3032,3033,3035,3037,3040,3042,3045,3047,3050,3052,3054,3056,3058],{"class":56,"line":179},[54,3034,1591],{"class":100},[54,3036,931],{"class":90},[54,3038,3039],{"class":127},"head",[54,3041,131],{"class":86},[54,3043,3044],{"class":90}," {value ",[54,3046,94],{"class":86},[54,3048,3049],{"class":90}," v, next ",[54,3051,94],{"class":86},[54,3053,1579],{"class":100},[54,3055,931],{"class":90},[54,3057,3039],{"class":127},[54,3059,273],{"class":90},[54,3061,3062,3064,3066,3068,3070,3073,3076,3078,3080,3082,3084,3086,3088,3090],{"class":56,"line":191},[54,3063,1013],{"class":86},[54,3065,2684],{"class":86},[54,3067,1579],{"class":100},[54,3069,931],{"class":90},[54,3071,3072],{"class":127},"tail",[54,3074,3075],{"class":86}," then",[54,3077,1579],{"class":100},[54,3079,931],{"class":90},[54,3081,3072],{"class":127},[54,3083,131],{"class":86},[54,3085,1579],{"class":100},[54,3087,931],{"class":90},[54,3089,3039],{"class":127},[54,3091,3092],{"class":86}," end\n",[54,3094,3095,3097,3099,3102,3104,3106,3108,3110,3112],{"class":56,"line":196},[54,3096,1591],{"class":100},[54,3098,931],{"class":90},[54,3100,3101],{"class":127},"size",[54,3103,131],{"class":86},[54,3105,1579],{"class":100},[54,3107,931],{"class":90},[54,3109,3101],{"class":127},[54,3111,623],{"class":86},[54,3113,1298],{"class":100},[54,3115,3116,3118],{"class":56,"line":202},[54,3117,852],{"class":86},[54,3119,1621],{"class":100},[54,3121,3122],{"class":56,"line":215},[54,3123,422],{"class":86},[54,3125,3126],{"class":56,"line":232},[54,3127,80],{"emptyLinePlaceholder":79},[54,3129,3130,3132,3134,3136,3139,3141],{"class":56,"line":249},[54,3131,1556],{"class":86},[54,3133,2968],{"class":127},[54,3135,1638],{"class":90},[54,3137,3138],{"class":127},"push_back",[54,3140,3027],{"class":90},[54,3142,3143],{"class":60},"-- O(1) (with tail pointer)\n",[54,3145,3146,3148,3151,3153,3155,3157,3159,3161,3163],{"class":56,"line":270},[54,3147,802],{"class":86},[54,3149,3150],{"class":90}," node ",[54,3152,94],{"class":86},[54,3154,3044],{"class":90},[54,3156,94],{"class":86},[54,3158,3049],{"class":90},[54,3160,94],{"class":86},[54,3162,2988],{"class":100},[54,3164,273],{"class":90},[54,3166,3167,3169,3171,3173,3175],{"class":56,"line":276},[54,3168,1013],{"class":86},[54,3170,1579],{"class":100},[54,3172,931],{"class":90},[54,3174,3072],{"class":127},[54,3176,3177],{"class":86}," then\n",[54,3179,3180,3183,3185,3187,3189,3192,3194],{"class":56,"line":281},[54,3181,3182],{"class":100},"    self",[54,3184,931],{"class":90},[54,3186,3072],{"class":127},[54,3188,931],{"class":90},[54,3190,3191],{"class":127},"next",[54,3193,131],{"class":86},[54,3195,3196],{"class":90}," node\n",[54,3198,3199],{"class":56,"line":287},[54,3200,3201],{"class":86},"  else\n",[54,3203,3204,3206,3208,3210,3212],{"class":56,"line":293},[54,3205,3182],{"class":100},[54,3207,931],{"class":90},[54,3209,3039],{"class":127},[54,3211,131],{"class":86},[54,3213,3196],{"class":90},[54,3215,3216],{"class":56,"line":328},[54,3217,847],{"class":86},[54,3219,3220,3222,3224,3226,3228],{"class":56,"line":1059},[54,3221,1591],{"class":100},[54,3223,931],{"class":90},[54,3225,3072],{"class":127},[54,3227,131],{"class":86},[54,3229,3196],{"class":90},[54,3231,3232,3234,3236,3238,3240,3242,3244,3246,3248],{"class":56,"line":1070},[54,3233,1591],{"class":100},[54,3235,931],{"class":90},[54,3237,3101],{"class":127},[54,3239,131],{"class":86},[54,3241,1579],{"class":100},[54,3243,931],{"class":90},[54,3245,3101],{"class":127},[54,3247,623],{"class":86},[54,3249,1298],{"class":100},[54,3251,3252,3254],{"class":56,"line":1084},[54,3253,852],{"class":86},[54,3255,1621],{"class":100},[54,3257,3258],{"class":56,"line":1099},[54,3259,422],{"class":86},[54,3261,3262],{"class":56,"line":1121},[54,3263,80],{"emptyLinePlaceholder":79},[54,3265,3266,3268,3270,3272,3275,3277],{"class":56,"line":1126},[54,3267,1556],{"class":86},[54,3269,2968],{"class":127},[54,3271,1638],{"class":90},[54,3273,3274],{"class":127},"pop_front",[54,3276,1442],{"class":90},[54,3278,3030],{"class":60},[54,3280,3281,3283,3285,3287,3289,3291,3293,3295,3297],{"class":56,"line":1146},[54,3282,1013],{"class":86},[54,3284,2684],{"class":86},[54,3286,1579],{"class":100},[54,3288,931],{"class":90},[54,3290,3039],{"class":127},[54,3292,3075],{"class":86},[54,3294,1022],{"class":86},[54,3296,2988],{"class":100},[54,3298,3092],{"class":86},[54,3300,3301,3303,3306,3308,3310,3312,3314,3316],{"class":56,"line":1151},[54,3302,802],{"class":86},[54,3304,3305],{"class":90}," v ",[54,3307,94],{"class":86},[54,3309,1579],{"class":100},[54,3311,931],{"class":90},[54,3313,3039],{"class":127},[54,3315,931],{"class":90},[54,3317,3318],{"class":127},"value\n",[54,3320,3321,3323,3325,3327,3329,3331,3333,3335,3337],{"class":56,"line":1156},[54,3322,1591],{"class":100},[54,3324,931],{"class":90},[54,3326,3039],{"class":127},[54,3328,131],{"class":86},[54,3330,1579],{"class":100},[54,3332,931],{"class":90},[54,3334,3039],{"class":127},[54,3336,931],{"class":90},[54,3338,3339],{"class":127},"next\n",[54,3341,3342,3344,3346,3348,3350,3352,3354,3356,3358,3360,3362,3364],{"class":56,"line":1168},[54,3343,1013],{"class":86},[54,3345,2684],{"class":86},[54,3347,1579],{"class":100},[54,3349,931],{"class":90},[54,3351,3039],{"class":127},[54,3353,3075],{"class":86},[54,3355,1579],{"class":100},[54,3357,931],{"class":90},[54,3359,3072],{"class":127},[54,3361,131],{"class":86},[54,3363,2988],{"class":100},[54,3365,3092],{"class":86},[54,3367,3368,3370,3372,3374,3376,3378,3380,3382,3385],{"class":56,"line":1185},[54,3369,1591],{"class":100},[54,3371,931],{"class":90},[54,3373,3101],{"class":127},[54,3375,131],{"class":86},[54,3377,1579],{"class":100},[54,3379,931],{"class":90},[54,3381,3101],{"class":127},[54,3383,3384],{"class":86}," -",[54,3386,1298],{"class":100},[54,3388,3389,3391],{"class":56,"line":1200},[54,3390,852],{"class":86},[54,3392,2711],{"class":90},[54,3394,3395],{"class":56,"line":2210},[54,3396,422],{"class":86},[54,3398,3399],{"class":56,"line":2215},[54,3400,80],{"emptyLinePlaceholder":79},[54,3402,3403,3405,3407,3409,3412,3414],{"class":56,"line":2229},[54,3404,1556],{"class":86},[54,3406,2968],{"class":127},[54,3408,1638],{"class":90},[54,3410,3411],{"class":127},"iter",[54,3413,1442],{"class":90},[54,3415,3416],{"class":60},"-- stateless iterator\n",[54,3418,3419,3421,3423,3426,3429,3432,3434,3436,3439,3442,3445,3447],{"class":56,"line":2250},[54,3420,802],{"class":86},[54,3422,600],{"class":86},[54,3424,3425],{"class":127}," walker",[54,3427,3428],{"class":90},"(node) ",[54,3430,3431],{"class":86},"return",[54,3433,3150],{"class":90},[54,3435,1476],{"class":86},[54,3437,3438],{"class":90}," node.",[54,3440,3441],{"class":127},"value",[54,3443,3444],{"class":90},", node.",[54,3446,3191],{"class":127},[54,3448,3092],{"class":86},[54,3450,3451,3453,3456,3458,3460],{"class":56,"line":2257},[54,3452,852],{"class":86},[54,3454,3455],{"class":100}," coroutine.wrap",[54,3457,492],{"class":90},[54,3459,1556],{"class":86},[54,3461,1435],{"class":90},[54,3463,3464,3467,3469,3471,3473,3475],{"class":56,"line":2262},[54,3465,3466],{"class":86},"    local",[54,3468,3150],{"class":90},[54,3470,94],{"class":86},[54,3472,1579],{"class":100},[54,3474,931],{"class":90},[54,3476,3477],{"class":127},"head\n",[54,3479,3480,3483,3485],{"class":56,"line":2289},[54,3481,3482],{"class":86},"    while",[54,3484,3150],{"class":90},[54,3486,829],{"class":86},[54,3488,3489,3492,3495,3497],{"class":56,"line":2773},[54,3490,3491],{"class":100},"      coroutine.yield",[54,3493,3494],{"class":90},"(node.",[54,3496,3441],{"class":127},[54,3498,1745],{"class":90},[54,3500,3501,3504,3506,3508],{"class":56,"line":2778},[54,3502,3503],{"class":90},"      node ",[54,3505,94],{"class":86},[54,3507,3438],{"class":90},[54,3509,3339],{"class":127},[54,3511,3512],{"class":56,"line":2793},[54,3513,2422],{"class":86},[54,3515,3516,3519],{"class":56,"line":2808},[54,3517,3518],{"class":86},"  end",[54,3520,1745],{"class":90},[54,3522,3523],{"class":56,"line":2813},[54,3524,422],{"class":86},[54,3526,3527],{"class":56,"line":2818},[54,3528,80],{"emptyLinePlaceholder":79},[54,3530,3531,3533,3536,3538,3541,3543],{"class":56,"line":2840},[54,3532,87],{"class":86},[54,3534,3535],{"class":90}," list ",[54,3537,94],{"class":86},[54,3539,3540],{"class":90}," List.",[54,3542,1564],{"class":100},[54,3544,1435],{"class":90},[54,3546,3547,3550,3552,3554,3556,3558,3560,3562,3564,3567,3569,3571,3573,3575],{"class":56,"line":2876},[54,3548,3549],{"class":127},"list",[54,3551,1638],{"class":90},[54,3553,3138],{"class":100},[54,3555,492],{"class":90},[54,3557,305],{"class":100},[54,3559,2097],{"class":90},[54,3561,3024],{"class":100},[54,3563,492],{"class":90},[54,3565,3566],{"class":100},"0",[54,3568,2097],{"class":90},[54,3570,3138],{"class":100},[54,3572,492],{"class":90},[54,3574,310],{"class":100},[54,3576,1745],{"class":90},[54,3578,3579,3581,3583,3585,3588,3590,3592,3595,3598,3601,3604,3607,3609,3611],{"class":56,"line":2899},[54,3580,388],{"class":86},[54,3582,3305],{"class":90},[54,3584,820],{"class":86},[54,3586,3587],{"class":127}," list",[54,3589,1638],{"class":90},[54,3591,3411],{"class":100},[54,3593,3594],{"class":90},"() ",[54,3596,3597],{"class":86},"do",[54,3599,3600],{"class":100}," io.write",[54,3602,3603],{"class":90},"(v, ",[54,3605,3606],{"class":134},"\" \"",[54,3608,969],{"class":90},[54,3610,1027],{"class":86},[54,3612,3613],{"class":60},"  -- 0 1 2\n",[338,3615,3617],{"id":3616},"ring-buffer-fixed-size-o1-pushpop","Ring buffer (fixed-size, O(1) push\u002Fpop)",[42,3619,3620,4127,4131],{"language":44},[46,3621,3623],{"className":48,"code":3622,"language":44,"meta":50,"style":50},"local RingBuffer = {}\nRingBuffer.__index = RingBuffer\n\nfunction RingBuffer.new(capacity)\n  return setmetatable({\n    buf = {}, capacity = capacity, head = 1, size = 0\n  }, RingBuffer)\nend\n\nfunction RingBuffer:push(v)\n  local idx = (self.head + self.size - 1) % self.capacity + 1\n  self.buf[idx] = v\n  if self.size \u003C self.capacity then\n    self.size = self.size + 1\n  else\n    self.head = (self.head % self.capacity) + 1  -- overwrite oldest, advance head\n  end\n  return self\nend\n\nfunction RingBuffer:pop()  -- oldest element\n  if self.size == 0 then return nil end\n  local v = self.buf[self.head]\n  self.buf[self.head] = nil  -- clear for GC\n  self.head = (self.head % self.capacity) + 1\n  self.size = self.size - 1\n  return v\nend\n\nlocal rb = RingBuffer.new(3)\nrb:push(\"a\"):push(\"b\"):push(\"c\"):push(\"d\")  -- overwrites \"a\"\nprint(rb:pop())  -- \"b\" (oldest remaining)\n",[32,3624,3625,3636,3648,3652,3666,3675,3700,3705,3709,3713,3727,3773,3789,3810,3830,3834,3870,3874,3880,3884,3888,3904,3926,3952,3977,4009,4029,4035,4039,4043,4064,4110],{"__ignoreMap":50},[54,3626,3627,3629,3632,3634],{"class":56,"line":57},[54,3628,87],{"class":86},[54,3630,3631],{"class":90}," RingBuffer ",[54,3633,94],{"class":86},[54,3635,383],{"class":90},[54,3637,3638,3641,3643,3645],{"class":56,"line":64},[54,3639,3640],{"class":90},"RingBuffer.",[54,3642,34],{"class":127},[54,3644,131],{"class":86},[54,3646,3647],{"class":90}," RingBuffer\n",[54,3649,3650],{"class":56,"line":70},[54,3651,80],{"emptyLinePlaceholder":79},[54,3653,3654,3656,3659,3661,3663],{"class":56,"line":76},[54,3655,1556],{"class":86},[54,3657,3658],{"class":127}," RingBuffer",[54,3660,931],{"class":90},[54,3662,1564],{"class":127},[54,3664,3665],{"class":90},"(capacity)\n",[54,3667,3668,3670,3672],{"class":56,"line":83},[54,3669,852],{"class":86},[54,3671,1131],{"class":100},[54,3673,3674],{"class":90},"({\n",[54,3676,3677,3680,3682,3685,3687,3690,3692,3694,3696,3698],{"class":56,"line":121},[54,3678,3679],{"class":90},"    buf ",[54,3681,94],{"class":86},[54,3683,3684],{"class":90}," {}, capacity ",[54,3686,94],{"class":86},[54,3688,3689],{"class":90}," capacity, head ",[54,3691,94],{"class":86},[54,3693,396],{"class":100},[54,3695,2998],{"class":90},[54,3697,94],{"class":86},[54,3699,2194],{"class":100},[54,3701,3702],{"class":56,"line":141},[54,3703,3704],{"class":90},"  }, RingBuffer)\n",[54,3706,3707],{"class":56,"line":161},[54,3708,422],{"class":86},[54,3710,3711],{"class":56,"line":179},[54,3712,80],{"emptyLinePlaceholder":79},[54,3714,3715,3717,3719,3721,3724],{"class":56,"line":191},[54,3716,1556],{"class":86},[54,3718,3658],{"class":127},[54,3720,1638],{"class":90},[54,3722,3723],{"class":127},"push",[54,3725,3726],{"class":90},"(v)\n",[54,3728,3729,3731,3734,3736,3739,3741,3743,3745,3747,3749,3751,3753,3755,3757,3759,3762,3764,3766,3769,3771],{"class":56,"line":196},[54,3730,802],{"class":86},[54,3732,3733],{"class":90}," idx ",[54,3735,94],{"class":86},[54,3737,3738],{"class":90}," (",[54,3740,1174],{"class":100},[54,3742,931],{"class":90},[54,3744,3039],{"class":127},[54,3746,623],{"class":86},[54,3748,1579],{"class":100},[54,3750,931],{"class":90},[54,3752,3101],{"class":127},[54,3754,3384],{"class":86},[54,3756,396],{"class":100},[54,3758,969],{"class":90},[54,3760,3761],{"class":86},"%",[54,3763,1579],{"class":100},[54,3765,931],{"class":90},[54,3767,3768],{"class":127},"capacity",[54,3770,623],{"class":86},[54,3772,1298],{"class":100},[54,3774,3775,3777,3779,3782,3785,3787],{"class":56,"line":202},[54,3776,1591],{"class":100},[54,3778,931],{"class":90},[54,3780,3781],{"class":127},"buf",[54,3783,3784],{"class":90},"[idx] ",[54,3786,94],{"class":86},[54,3788,2711],{"class":90},[54,3790,3791,3793,3795,3797,3799,3802,3804,3806,3808],{"class":56,"line":215},[54,3792,1013],{"class":86},[54,3794,1579],{"class":100},[54,3796,931],{"class":90},[54,3798,3101],{"class":127},[54,3800,3801],{"class":86}," \u003C",[54,3803,1579],{"class":100},[54,3805,931],{"class":90},[54,3807,3768],{"class":127},[54,3809,3177],{"class":86},[54,3811,3812,3814,3816,3818,3820,3822,3824,3826,3828],{"class":56,"line":232},[54,3813,3182],{"class":100},[54,3815,931],{"class":90},[54,3817,3101],{"class":127},[54,3819,131],{"class":86},[54,3821,1579],{"class":100},[54,3823,931],{"class":90},[54,3825,3101],{"class":127},[54,3827,623],{"class":86},[54,3829,1298],{"class":100},[54,3831,3832],{"class":56,"line":249},[54,3833,3201],{"class":86},[54,3835,3836,3838,3840,3842,3844,3846,3848,3850,3852,3855,3857,3859,3861,3863,3865,3867],{"class":56,"line":270},[54,3837,3182],{"class":100},[54,3839,931],{"class":90},[54,3841,3039],{"class":127},[54,3843,131],{"class":86},[54,3845,3738],{"class":90},[54,3847,1174],{"class":100},[54,3849,931],{"class":90},[54,3851,3039],{"class":127},[54,3853,3854],{"class":86}," %",[54,3856,1579],{"class":100},[54,3858,931],{"class":90},[54,3860,3768],{"class":127},[54,3862,969],{"class":90},[54,3864,1295],{"class":86},[54,3866,396],{"class":100},[54,3868,3869],{"class":60},"  -- overwrite oldest, advance head\n",[54,3871,3872],{"class":56,"line":276},[54,3873,847],{"class":86},[54,3875,3876,3878],{"class":56,"line":281},[54,3877,852],{"class":86},[54,3879,1621],{"class":100},[54,3881,3882],{"class":56,"line":287},[54,3883,422],{"class":86},[54,3885,3886],{"class":56,"line":293},[54,3887,80],{"emptyLinePlaceholder":79},[54,3889,3890,3892,3894,3896,3899,3901],{"class":56,"line":328},[54,3891,1556],{"class":86},[54,3893,3658],{"class":127},[54,3895,1638],{"class":90},[54,3897,3898],{"class":127},"pop",[54,3900,1442],{"class":90},[54,3902,3903],{"class":60},"-- oldest element\n",[54,3905,3906,3908,3910,3912,3914,3916,3918,3920,3922,3924],{"class":56,"line":1059},[54,3907,1013],{"class":86},[54,3909,1579],{"class":100},[54,3911,931],{"class":90},[54,3913,3101],{"class":127},[54,3915,1210],{"class":86},[54,3917,466],{"class":100},[54,3919,3075],{"class":86},[54,3921,1022],{"class":86},[54,3923,2988],{"class":100},[54,3925,3092],{"class":86},[54,3927,3928,3930,3932,3934,3936,3938,3940,3943,3945,3947,3949],{"class":56,"line":1070},[54,3929,802],{"class":86},[54,3931,3305],{"class":90},[54,3933,94],{"class":86},[54,3935,1579],{"class":100},[54,3937,931],{"class":90},[54,3939,3781],{"class":127},[54,3941,3942],{"class":90},"[",[54,3944,1174],{"class":100},[54,3946,931],{"class":90},[54,3948,3039],{"class":127},[54,3950,3951],{"class":90},"]\n",[54,3953,3954,3956,3958,3960,3962,3964,3966,3968,3970,3972,3974],{"class":56,"line":1084},[54,3955,1591],{"class":100},[54,3957,931],{"class":90},[54,3959,3781],{"class":127},[54,3961,3942],{"class":90},[54,3963,1174],{"class":100},[54,3965,931],{"class":90},[54,3967,3039],{"class":127},[54,3969,150],{"class":90},[54,3971,94],{"class":86},[54,3973,2988],{"class":100},[54,3975,3976],{"class":60},"  -- clear for GC\n",[54,3978,3979,3981,3983,3985,3987,3989,3991,3993,3995,3997,3999,4001,4003,4005,4007],{"class":56,"line":1099},[54,3980,1591],{"class":100},[54,3982,931],{"class":90},[54,3984,3039],{"class":127},[54,3986,131],{"class":86},[54,3988,3738],{"class":90},[54,3990,1174],{"class":100},[54,3992,931],{"class":90},[54,3994,3039],{"class":127},[54,3996,3854],{"class":86},[54,3998,1579],{"class":100},[54,4000,931],{"class":90},[54,4002,3768],{"class":127},[54,4004,969],{"class":90},[54,4006,1295],{"class":86},[54,4008,1298],{"class":100},[54,4010,4011,4013,4015,4017,4019,4021,4023,4025,4027],{"class":56,"line":1121},[54,4012,1591],{"class":100},[54,4014,931],{"class":90},[54,4016,3101],{"class":127},[54,4018,131],{"class":86},[54,4020,1579],{"class":100},[54,4022,931],{"class":90},[54,4024,3101],{"class":127},[54,4026,3384],{"class":86},[54,4028,1298],{"class":100},[54,4030,4031,4033],{"class":56,"line":1126},[54,4032,852],{"class":86},[54,4034,2711],{"class":90},[54,4036,4037],{"class":56,"line":1146},[54,4038,422],{"class":86},[54,4040,4041],{"class":56,"line":1151},[54,4042,80],{"emptyLinePlaceholder":79},[54,4044,4045,4047,4050,4052,4055,4057,4059,4062],{"class":56,"line":1156},[54,4046,87],{"class":86},[54,4048,4049],{"class":90}," rb ",[54,4051,94],{"class":86},[54,4053,4054],{"class":90}," RingBuffer.",[54,4056,1564],{"class":100},[54,4058,492],{"class":90},[54,4060,4061],{"class":100},"3",[54,4063,1745],{"class":90},[54,4065,4066,4069,4071,4073,4075,4078,4080,4082,4084,4087,4089,4091,4093,4096,4098,4100,4102,4105,4107],{"class":56,"line":1168},[54,4067,4068],{"class":127},"rb",[54,4070,1638],{"class":90},[54,4072,3723],{"class":100},[54,4074,492],{"class":90},[54,4076,4077],{"class":134},"\"a\"",[54,4079,2097],{"class":90},[54,4081,3723],{"class":100},[54,4083,492],{"class":90},[54,4085,4086],{"class":134},"\"b\"",[54,4088,2097],{"class":90},[54,4090,3723],{"class":100},[54,4092,492],{"class":90},[54,4094,4095],{"class":134},"\"c\"",[54,4097,2097],{"class":90},[54,4099,3723],{"class":100},[54,4101,492],{"class":90},[54,4103,4104],{"class":134},"\"d\"",[54,4106,767],{"class":90},[54,4108,4109],{"class":60},"-- overwrites \"a\"\n",[54,4111,4112,4114,4116,4118,4120,4122,4124],{"class":56,"line":1185},[54,4113,573],{"class":100},[54,4115,492],{"class":90},[54,4117,4068],{"class":127},[54,4119,1638],{"class":90},[54,4121,3898],{"class":100},[54,4123,1761],{"class":90},[54,4125,4126],{"class":60},"-- \"b\" (oldest remaining)\n",[338,4128,4130],{"id":4129},"object-pool-reuse-allocations-reduce-gc-pressure","Object pool (reuse allocations, reduce GC pressure)",[42,4132,4133,4558,4571],{"language":44},[46,4134,4136],{"className":48,"code":4135,"language":44,"meta":50,"style":50},"local Pool = {}\nPool.__index = Pool\n\nfunction Pool.new(factory, reset_fn, max_size)\n  return setmetatable({\n    free = {}, factory = factory, reset_fn = reset_fn, max = max_size or 100\n  }, Pool)\nend\n\nfunction Pool:acquire()\n  if #self.free > 0 then\n    return table.remove(self.free)  -- reuse existing object\n  end\n  return self.factory()  -- create new if pool empty\nend\n\nfunction Pool:release(obj)\n  if self.reset_fn then self.reset_fn(obj) end  -- clear state for reuse\n  if #self.free \u003C self.max then\n    self.free[#self.free + 1] = obj  -- return to pool\n  end\n  -- else: let GC collect (pool full)\nend\n\n-- Usage: pool of buffers (avoid allocation in hot loop)\nlocal buffer_pool = Pool.new(\n  function() return {data = {}} end,\n  function(buf) buf.data = {} end,  -- reset: clear data\n  50\n)\nlocal buf = buffer_pool:acquire()\nbuf.data[1] = 42\n-- ... use buf ...\nbuffer_pool:release(buf)  -- return for reuse, no GC\n",[32,4137,4138,4149,4161,4165,4179,4187,4217,4222,4226,4230,4243,4264,4285,4289,4305,4309,4313,4327,4354,4377,4409,4413,4418,4422,4426,4431,4448,4470,4493,4498,4502,4520,4538,4543],{"__ignoreMap":50},[54,4139,4140,4142,4145,4147],{"class":56,"line":57},[54,4141,87],{"class":86},[54,4143,4144],{"class":90}," Pool ",[54,4146,94],{"class":86},[54,4148,383],{"class":90},[54,4150,4151,4154,4156,4158],{"class":56,"line":64},[54,4152,4153],{"class":90},"Pool.",[54,4155,34],{"class":127},[54,4157,131],{"class":86},[54,4159,4160],{"class":90}," Pool\n",[54,4162,4163],{"class":56,"line":70},[54,4164,80],{"emptyLinePlaceholder":79},[54,4166,4167,4169,4172,4174,4176],{"class":56,"line":76},[54,4168,1556],{"class":86},[54,4170,4171],{"class":127}," Pool",[54,4173,931],{"class":90},[54,4175,1564],{"class":127},[54,4177,4178],{"class":90},"(factory, reset_fn, max_size)\n",[54,4180,4181,4183,4185],{"class":56,"line":83},[54,4182,852],{"class":86},[54,4184,1131],{"class":100},[54,4186,3674],{"class":90},[54,4188,4189,4192,4194,4197,4199,4202,4204,4207,4209,4212,4214],{"class":56,"line":121},[54,4190,4191],{"class":90},"    free ",[54,4193,94],{"class":86},[54,4195,4196],{"class":90}," {}, factory ",[54,4198,94],{"class":86},[54,4200,4201],{"class":90}," factory, reset_fn ",[54,4203,94],{"class":86},[54,4205,4206],{"class":90}," reset_fn, max ",[54,4208,94],{"class":86},[54,4210,4211],{"class":90}," max_size ",[54,4213,1006],{"class":86},[54,4215,4216],{"class":100}," 100\n",[54,4218,4219],{"class":56,"line":141},[54,4220,4221],{"class":90},"  }, Pool)\n",[54,4223,4224],{"class":56,"line":161},[54,4225,422],{"class":86},[54,4227,4228],{"class":56,"line":179},[54,4229,80],{"emptyLinePlaceholder":79},[54,4231,4232,4234,4236,4238,4241],{"class":56,"line":191},[54,4233,1556],{"class":86},[54,4235,4171],{"class":127},[54,4237,1638],{"class":90},[54,4239,4240],{"class":127},"acquire",[54,4242,1435],{"class":90},[54,4244,4245,4247,4250,4252,4254,4257,4260,4262],{"class":56,"line":196},[54,4246,1013],{"class":86},[54,4248,4249],{"class":86}," #",[54,4251,1174],{"class":100},[54,4253,931],{"class":90},[54,4255,4256],{"class":127},"free",[54,4258,4259],{"class":86}," >",[54,4261,466],{"class":100},[54,4263,3177],{"class":86},[54,4265,4266,4269,4272,4274,4276,4278,4280,4282],{"class":56,"line":202},[54,4267,4268],{"class":86},"    return",[54,4270,4271],{"class":100}," table.remove",[54,4273,492],{"class":90},[54,4275,1174],{"class":100},[54,4277,931],{"class":90},[54,4279,4256],{"class":127},[54,4281,767],{"class":90},[54,4283,4284],{"class":60},"-- reuse existing object\n",[54,4286,4287],{"class":56,"line":215},[54,4288,847],{"class":86},[54,4290,4291,4293,4295,4297,4300,4302],{"class":56,"line":232},[54,4292,852],{"class":86},[54,4294,1579],{"class":100},[54,4296,931],{"class":90},[54,4298,4299],{"class":100},"factory",[54,4301,1442],{"class":90},[54,4303,4304],{"class":60},"-- create new if pool empty\n",[54,4306,4307],{"class":56,"line":249},[54,4308,422],{"class":86},[54,4310,4311],{"class":56,"line":270},[54,4312,80],{"emptyLinePlaceholder":79},[54,4314,4315,4317,4319,4321,4324],{"class":56,"line":276},[54,4316,1556],{"class":86},[54,4318,4171],{"class":127},[54,4320,1638],{"class":90},[54,4322,4323],{"class":127},"release",[54,4325,4326],{"class":90},"(obj)\n",[54,4328,4329,4331,4333,4335,4338,4340,4342,4344,4346,4349,4351],{"class":56,"line":281},[54,4330,1013],{"class":86},[54,4332,1579],{"class":100},[54,4334,931],{"class":90},[54,4336,4337],{"class":127},"reset_fn",[54,4339,3075],{"class":86},[54,4341,1579],{"class":100},[54,4343,931],{"class":90},[54,4345,4337],{"class":100},[54,4347,4348],{"class":90},"(obj) ",[54,4350,1027],{"class":86},[54,4352,4353],{"class":60},"  -- clear state for reuse\n",[54,4355,4356,4358,4360,4362,4364,4366,4368,4370,4372,4375],{"class":56,"line":287},[54,4357,1013],{"class":86},[54,4359,4249],{"class":86},[54,4361,1174],{"class":100},[54,4363,931],{"class":90},[54,4365,4256],{"class":127},[54,4367,3801],{"class":86},[54,4369,1579],{"class":100},[54,4371,931],{"class":90},[54,4373,4374],{"class":127},"max",[54,4376,3177],{"class":86},[54,4378,4379,4381,4383,4385,4387,4389,4391,4393,4395,4397,4399,4401,4403,4406],{"class":56,"line":293},[54,4380,3182],{"class":100},[54,4382,931],{"class":90},[54,4384,4256],{"class":127},[54,4386,3942],{"class":90},[54,4388,182],{"class":86},[54,4390,1174],{"class":100},[54,4392,931],{"class":90},[54,4394,4256],{"class":127},[54,4396,623],{"class":86},[54,4398,396],{"class":100},[54,4400,150],{"class":90},[54,4402,94],{"class":86},[54,4404,4405],{"class":90}," obj  ",[54,4407,4408],{"class":60},"-- return to pool\n",[54,4410,4411],{"class":56,"line":328},[54,4412,847],{"class":86},[54,4414,4415],{"class":56,"line":1059},[54,4416,4417],{"class":60},"  -- else: let GC collect (pool full)\n",[54,4419,4420],{"class":56,"line":1070},[54,4421,422],{"class":86},[54,4423,4424],{"class":56,"line":1084},[54,4425,80],{"emptyLinePlaceholder":79},[54,4427,4428],{"class":56,"line":1099},[54,4429,4430],{"class":60},"-- Usage: pool of buffers (avoid allocation in hot loop)\n",[54,4432,4433,4435,4438,4440,4443,4445],{"class":56,"line":1121},[54,4434,87],{"class":86},[54,4436,4437],{"class":90}," buffer_pool ",[54,4439,94],{"class":86},[54,4441,4442],{"class":90}," Pool.",[54,4444,1564],{"class":100},[54,4446,4447],{"class":90},"(\n",[54,4449,4450,4453,4455,4457,4460,4462,4465,4467],{"class":56,"line":1126},[54,4451,4452],{"class":86},"  function",[54,4454,3594],{"class":90},[54,4456,3431],{"class":86},[54,4458,4459],{"class":90}," {data ",[54,4461,94],{"class":86},[54,4463,4464],{"class":90}," {}} ",[54,4466,1027],{"class":86},[54,4468,4469],{"class":90},",\n",[54,4471,4472,4474,4477,4480,4482,4485,4487,4490],{"class":56,"line":1146},[54,4473,4452],{"class":86},[54,4475,4476],{"class":90},"(buf) buf.",[54,4478,4479],{"class":127},"data",[54,4481,131],{"class":86},[54,4483,4484],{"class":90}," {} ",[54,4486,1027],{"class":86},[54,4488,4489],{"class":90},",  ",[54,4491,4492],{"class":60},"-- reset: clear data\n",[54,4494,4495],{"class":56,"line":1151},[54,4496,4497],{"class":100},"  50\n",[54,4499,4500],{"class":56,"line":1156},[54,4501,1745],{"class":90},[54,4503,4504,4506,4509,4511,4514,4516,4518],{"class":56,"line":1168},[54,4505,87],{"class":86},[54,4507,4508],{"class":90}," buf ",[54,4510,94],{"class":86},[54,4512,4513],{"class":127}," buffer_pool",[54,4515,1638],{"class":90},[54,4517,4240],{"class":100},[54,4519,1435],{"class":90},[54,4521,4522,4525,4527,4529,4531,4533,4535],{"class":56,"line":1185},[54,4523,4524],{"class":90},"buf.",[54,4526,4479],{"class":127},[54,4528,3942],{"class":90},[54,4530,305],{"class":100},[54,4532,150],{"class":90},[54,4534,94],{"class":86},[54,4536,4537],{"class":100}," 42\n",[54,4539,4540],{"class":56,"line":1200},[54,4541,4542],{"class":60},"-- ... use buf ...\n",[54,4544,4545,4548,4550,4552,4555],{"class":56,"line":2210},[54,4546,4547],{"class":127},"buffer_pool",[54,4549,1638],{"class":90},[54,4551,4323],{"class":100},[54,4553,4554],{"class":90},"(buf)  ",[54,4556,4557],{"class":60},"-- return for reuse, no GC\n",[37,4559,4561,4562,104,4565,104,4568],{"id":4560},"table-library-tablemove-tablesort-tableconcat","Table Library: ",[32,4563,4564],{},"table.move",[32,4566,4567],{},"table.sort",[32,4569,4570],{},"table.concat",[42,4572,4573,4915,4919,4929],{"language":44},[46,4574,4576],{"className":48,"code":4575,"language":44,"meta":50,"style":50},"-- table.move(src, f, e, t, dest?): move elements src[f..e] to dest starting at t\nlocal src = {10, 20, 30, 40, 50}\nlocal dest = {}\ntable.move(src, 2, 4, 1, dest)  -- dest = {20, 30, 40}\n-- In-place move (overlapping regions):\nlocal a = {1, 2, 3, 4, 5}\ntable.move(a, 1, 3, 3)  -- a = {1, 2, 1, 2, 3} (shifted right)\n\n-- table.sort: in-place, stable in 5.4+. Only sorts array part (1..n).\nlocal nums = {5, 3, 1, 4, 2}\ntable.sort(nums)  -- {1, 2, 3, 4, 5}\ntable.sort(nums, function(a, b) return a > b end)  -- descending: {5, 4, 3, 2, 1}\n\n-- Multi-key sort: sort by one field, then another (stable sort in reverse priority)\nlocal users = {{name=\"B\", age=30}, {name=\"A\", age=30}, {name=\"C\", age=25}}\ntable.sort(users, function(a, b) return a.age \u003C b.age end)  -- primary: age\ntable.sort(users, function(a, b) return a.name \u003C b.name end)  -- secondary: name\n-- Result: A(30), B(30), C(25) → sorted by name, then age (stable sort preserves)\n",[32,4577,4578,4583,4616,4627,4650,4655,4685,4707,4711,4716,4747,4757,4785,4789,4794,4848,4881,4910],{"__ignoreMap":50},[54,4579,4580],{"class":56,"line":57},[54,4581,4582],{"class":60},"-- table.move(src, f, e, t, dest?): move elements src[f..e] to dest starting at t\n",[54,4584,4585,4587,4590,4592,4594,4596,4598,4600,4602,4604,4606,4609,4611,4614],{"class":56,"line":64},[54,4586,87],{"class":86},[54,4588,4589],{"class":90}," src ",[54,4591,94],{"class":86},[54,4593,97],{"class":90},[54,4595,101],{"class":100},[54,4597,104],{"class":90},[54,4599,107],{"class":100},[54,4601,104],{"class":90},[54,4603,112],{"class":100},[54,4605,104],{"class":90},[54,4607,4608],{"class":100},"40",[54,4610,104],{"class":90},[54,4612,4613],{"class":100},"50",[54,4615,273],{"class":90},[54,4617,4618,4620,4623,4625],{"class":56,"line":70},[54,4619,87],{"class":86},[54,4621,4622],{"class":90}," dest ",[54,4624,94],{"class":86},[54,4626,383],{"class":90},[54,4628,4629,4631,4634,4636,4638,4640,4642,4644,4647],{"class":56,"line":76},[54,4630,4564],{"class":100},[54,4632,4633],{"class":90},"(src, ",[54,4635,310],{"class":100},[54,4637,104],{"class":90},[54,4639,166],{"class":100},[54,4641,104],{"class":90},[54,4643,305],{"class":100},[54,4645,4646],{"class":90},", dest)  ",[54,4648,4649],{"class":60},"-- dest = {20, 30, 40}\n",[54,4651,4652],{"class":56,"line":83},[54,4653,4654],{"class":60},"-- In-place move (overlapping regions):\n",[54,4656,4657,4659,4661,4663,4665,4667,4669,4671,4673,4675,4677,4679,4681,4683],{"class":56,"line":121},[54,4658,87],{"class":86},[54,4660,529],{"class":90},[54,4662,94],{"class":86},[54,4664,97],{"class":90},[54,4666,305],{"class":100},[54,4668,104],{"class":90},[54,4670,310],{"class":100},[54,4672,104],{"class":90},[54,4674,4061],{"class":100},[54,4676,104],{"class":90},[54,4678,166],{"class":100},[54,4680,104],{"class":90},[54,4682,147],{"class":100},[54,4684,273],{"class":90},[54,4686,4687,4689,4692,4694,4696,4698,4700,4702,4704],{"class":56,"line":141},[54,4688,4564],{"class":100},[54,4690,4691],{"class":90},"(a, ",[54,4693,305],{"class":100},[54,4695,104],{"class":90},[54,4697,4061],{"class":100},[54,4699,104],{"class":90},[54,4701,4061],{"class":100},[54,4703,767],{"class":90},[54,4705,4706],{"class":60},"-- a = {1, 2, 1, 2, 3} (shifted right)\n",[54,4708,4709],{"class":56,"line":161},[54,4710,80],{"emptyLinePlaceholder":79},[54,4712,4713],{"class":56,"line":179},[54,4714,4715],{"class":60},"-- table.sort: in-place, stable in 5.4+. Only sorts array part (1..n).\n",[54,4717,4718,4720,4723,4725,4727,4729,4731,4733,4735,4737,4739,4741,4743,4745],{"class":56,"line":191},[54,4719,87],{"class":86},[54,4721,4722],{"class":90}," nums ",[54,4724,94],{"class":86},[54,4726,97],{"class":90},[54,4728,147],{"class":100},[54,4730,104],{"class":90},[54,4732,4061],{"class":100},[54,4734,104],{"class":90},[54,4736,305],{"class":100},[54,4738,104],{"class":90},[54,4740,166],{"class":100},[54,4742,104],{"class":90},[54,4744,310],{"class":100},[54,4746,273],{"class":90},[54,4748,4749,4751,4754],{"class":56,"line":196},[54,4750,4567],{"class":100},[54,4752,4753],{"class":90},"(nums)  ",[54,4755,4756],{"class":60},"-- {1, 2, 3, 4, 5}\n",[54,4758,4759,4761,4764,4766,4769,4771,4773,4776,4778,4780,4782],{"class":56,"line":202},[54,4760,4567],{"class":100},[54,4762,4763],{"class":90},"(nums, ",[54,4765,1556],{"class":86},[54,4767,4768],{"class":90},"(a, b) ",[54,4770,3431],{"class":86},[54,4772,529],{"class":90},[54,4774,4775],{"class":86},">",[54,4777,547],{"class":90},[54,4779,1027],{"class":86},[54,4781,767],{"class":90},[54,4783,4784],{"class":60},"-- descending: {5, 4, 3, 2, 1}\n",[54,4786,4787],{"class":56,"line":215},[54,4788,80],{"emptyLinePlaceholder":79},[54,4790,4791],{"class":56,"line":232},[54,4792,4793],{"class":60},"-- Multi-key sort: sort by one field, then another (stable sort in reverse priority)\n",[54,4795,4796,4798,4801,4803,4806,4808,4811,4814,4816,4818,4821,4823,4826,4828,4830,4832,4834,4836,4839,4841,4843,4846],{"class":56,"line":249},[54,4797,87],{"class":86},[54,4799,4800],{"class":90}," users ",[54,4802,94],{"class":86},[54,4804,4805],{"class":90}," {{name",[54,4807,94],{"class":86},[54,4809,4810],{"class":134},"\"B\"",[54,4812,4813],{"class":90},", age",[54,4815,94],{"class":86},[54,4817,112],{"class":100},[54,4819,4820],{"class":90},"}, {name",[54,4822,94],{"class":86},[54,4824,4825],{"class":134},"\"A\"",[54,4827,4813],{"class":90},[54,4829,94],{"class":86},[54,4831,112],{"class":100},[54,4833,4820],{"class":90},[54,4835,94],{"class":86},[54,4837,4838],{"class":134},"\"C\"",[54,4840,4813],{"class":90},[54,4842,94],{"class":86},[54,4844,4845],{"class":100},"25",[54,4847,895],{"class":90},[54,4849,4850,4852,4855,4857,4859,4861,4864,4866,4868,4871,4873,4876,4878],{"class":56,"line":270},[54,4851,4567],{"class":100},[54,4853,4854],{"class":90},"(users, ",[54,4856,1556],{"class":86},[54,4858,4768],{"class":90},[54,4860,3431],{"class":86},[54,4862,4863],{"class":90}," a.",[54,4865,2189],{"class":127},[54,4867,3801],{"class":86},[54,4869,4870],{"class":90}," b.",[54,4872,2189],{"class":127},[54,4874,4875],{"class":86}," end",[54,4877,767],{"class":90},[54,4879,4880],{"class":60},"-- primary: age\n",[54,4882,4883,4885,4887,4889,4891,4893,4895,4897,4899,4901,4903,4905,4907],{"class":56,"line":276},[54,4884,4567],{"class":100},[54,4886,4854],{"class":90},[54,4888,1556],{"class":86},[54,4890,4768],{"class":90},[54,4892,3431],{"class":86},[54,4894,4863],{"class":90},[54,4896,128],{"class":127},[54,4898,3801],{"class":86},[54,4900,4870],{"class":90},[54,4902,128],{"class":127},[54,4904,4875],{"class":86},[54,4906,767],{"class":90},[54,4908,4909],{"class":60},"-- secondary: name\n",[54,4911,4912],{"class":56,"line":281},[54,4913,4914],{"class":60},"-- Result: A(30), B(30), C(25) → sorted by name, then age (stable sort preserves)\n",[37,4916,4918],{"id":4917},"tips-tricks","💡 Tips & Tricks",[15,4920,4921,4928],{},[19,4922,4923,4924,4927],{},"Use ",[32,4925,4926],{},"next(t)"," to check if a table is empty",": O(1), no iteration.",[42,4930,4931],{"language":44},[46,4932,4934],{"className":48,"code":4933,"language":44,"meta":50,"style":50},"local function is_empty(t) return next(t) == nil end\n",[32,4935,4936],{"__ignoreMap":50},[54,4937,4938,4940,4942,4945,4947,4949,4952,4954,4956,4958],{"class":56,"line":57},[54,4939,87],{"class":86},[54,4941,600],{"class":86},[54,4943,4944],{"class":127}," is_empty",[54,4946,826],{"class":90},[54,4948,3431],{"class":86},[54,4950,4951],{"class":100}," next",[54,4953,826],{"class":90},[54,4955,721],{"class":86},[54,4957,2988],{"class":100},[54,4959,3092],{"class":86},[15,4961,4962,4967],{},[19,4963,4964,4966],{},[32,4965,4570],{}," is the fastest way to build large strings",": Single allocation, no intermediate strings.",[42,4969,4970],{"language":44},[46,4971,4973],{"className":48,"code":4972,"language":44,"meta":50,"style":50},"-- CSV builder: 100K rows, 10 columns → 1M string fragments\nlocal rows = {}\nfor i = 1, 100000 do\n  rows[i] = table.concat({i, \"name\" .. i, \"val\" .. i, '\"quoted\"'} , \",\")\nend\nlocal csv = table.concat(rows, \"\\n\")  -- 2 concats total: per-row, then all rows\n",[32,4974,4975,4980,4991,5008,5047,5051],{"__ignoreMap":50},[54,4976,4977],{"class":56,"line":57},[54,4978,4979],{"class":60},"-- CSV builder: 100K rows, 10 columns → 1M string fragments\n",[54,4981,4982,4984,4987,4989],{"class":56,"line":64},[54,4983,87],{"class":86},[54,4985,4986],{"class":90}," rows ",[54,4988,94],{"class":86},[54,4990,383],{"class":90},[54,4992,4993,4995,4997,4999,5001,5003,5006],{"class":56,"line":70},[54,4994,388],{"class":86},[54,4996,391],{"class":90},[54,4998,94],{"class":86},[54,5000,396],{"class":100},[54,5002,104],{"class":90},[54,5004,5005],{"class":100},"100000",[54,5007,404],{"class":86},[54,5009,5010,5013,5015,5018,5021,5024,5026,5029,5032,5034,5036,5039,5042,5045],{"class":56,"line":76},[54,5011,5012],{"class":90},"  rows[i] ",[54,5014,94],{"class":86},[54,5016,5017],{"class":100}," table.concat",[54,5019,5020],{"class":90},"({i, ",[54,5022,5023],{"class":134},"\"name\" ",[54,5025,1662],{"class":86},[54,5027,5028],{"class":90}," i, ",[54,5030,5031],{"class":134},"\"val\" ",[54,5033,1662],{"class":86},[54,5035,5028],{"class":90},[54,5037,5038],{"class":134},"'\"quoted\"'",[54,5040,5041],{"class":90},"} , ",[54,5043,5044],{"class":134},"\",\"",[54,5046,1745],{"class":90},[54,5048,5049],{"class":56,"line":83},[54,5050,422],{"class":86},[54,5052,5053,5055,5058,5060,5062,5065,5068,5071,5073,5075],{"class":56,"line":121},[54,5054,87],{"class":86},[54,5056,5057],{"class":90}," csv ",[54,5059,94],{"class":86},[54,5061,5017],{"class":100},[54,5063,5064],{"class":90},"(rows, ",[54,5066,5067],{"class":134},"\"",[54,5069,5070],{"class":100},"\\n",[54,5072,5067],{"class":134},[54,5074,767],{"class":90},[54,5076,5077],{"class":60},"-- 2 concats total: per-row, then all rows\n",[15,5079,5080,5085],{},[19,5081,4923,5082,5084],{},[32,5083,34],{}," as a table for method sharing, not a function",": Table lookup is faster than function call lookup.",[42,5087,5088],{"language":44},[46,5089,5091],{"className":48,"code":5090,"language":44,"meta":50,"style":50},"-- SLOWER: __index as function (called on every miss)\nsetmetatable(obj, {__index = function(t, k) return methods[k] end})\n\n-- FASTER: __index as table (direct table lookup, no function call overhead)\nsetmetatable(obj, {__index = methods})\n",[32,5092,5093,5098,5125,5129,5134],{"__ignoreMap":50},[54,5094,5095],{"class":56,"line":57},[54,5096,5097],{"class":60},"-- SLOWER: __index as function (called on every miss)\n",[54,5099,5100,5103,5106,5108,5110,5112,5115,5117,5120,5122],{"class":56,"line":64},[54,5101,5102],{"class":100},"setmetatable",[54,5104,5105],{"class":90},"(obj, {",[54,5107,34],{"class":127},[54,5109,131],{"class":86},[54,5111,600],{"class":86},[54,5113,5114],{"class":90},"(t, k) ",[54,5116,3431],{"class":86},[54,5118,5119],{"class":90}," methods[k] ",[54,5121,1027],{"class":86},[54,5123,5124],{"class":90},"})\n",[54,5126,5127],{"class":56,"line":70},[54,5128,80],{"emptyLinePlaceholder":79},[54,5130,5131],{"class":56,"line":76},[54,5132,5133],{"class":60},"-- FASTER: __index as table (direct table lookup, no function call overhead)\n",[54,5135,5136,5138,5141,5143],{"class":56,"line":83},[54,5137,5102],{"class":100},[54,5139,5140],{"class":90},"(obj, {__index ",[54,5142,94],{"class":86},[54,5144,5145],{"class":90}," methods})\n",[37,5147,5149],{"id":5148},"️-edge-cases-gotchas","⚠️ Edge Cases & Gotchas",[15,5151,5152,5157],{},[19,5153,5154,5156],{},[32,5155,4567],{}," only sorts the array part",": Hash keys (string keys, non-contiguous integer keys) are not sorted. Collect them into an array first.",[42,5159,5160],{"language":44},[46,5161,5163],{"className":48,"code":5162,"language":44,"meta":50,"style":50},"local t = {3, 1, name = \"X\", 2}\ntable.sort(t)  -- sorts array part: {1, 2, 3}; name=\"X\" untouched\n",[32,5164,5165,5195],{"__ignoreMap":50},[54,5166,5167,5169,5171,5173,5175,5177,5179,5181,5184,5186,5189,5191,5193],{"class":56,"line":57},[54,5168,87],{"class":86},[54,5170,91],{"class":90},[54,5172,94],{"class":86},[54,5174,97],{"class":90},[54,5176,4061],{"class":100},[54,5178,104],{"class":90},[54,5180,305],{"class":100},[54,5182,5183],{"class":90},", name ",[54,5185,94],{"class":86},[54,5187,5188],{"class":134}," \"X\"",[54,5190,104],{"class":90},[54,5192,310],{"class":100},[54,5194,273],{"class":90},[54,5196,5197,5199,5202],{"class":56,"line":64},[54,5198,4567],{"class":100},[54,5200,5201],{"class":90},"(t)  ",[54,5203,5204],{"class":60},"-- sorts array part: {1, 2, 3}; name=\"X\" untouched\n",[15,5206,5207,5214],{},[19,5208,5209,5210,5213],{},"Modifying a table during ",[32,5211,5212],{},"pairs"," iteration is undefined behavior",": Adding new keys may or may not be visited; removing keys may cause nil access.",[42,5216,5217],{"language":44},[46,5218,5220],{"className":48,"code":5219,"language":44,"meta":50,"style":50},"local t = {a = 1, b = 2, c = 3}\nfor k in pairs(t) do\n  t[k .. \"_new\"] = t[k]  -- adding keys during iteration — UNDEFINED\nend\n-- Some new keys may be visited, some may not. Don't do this.\n\n-- SAFE: collect keys first, then modify\nlocal keys = {}\nfor k in pairs(t) do keys[#keys + 1] = k end\nfor _, k in ipairs(keys) do\n  t[k .. \"_new\"] = t[k]  -- safe: iterating a separate array\nend\n",[32,5221,5222,5253,5267,5287,5291,5296,5300,5305,5316,5350,5366,5383],{"__ignoreMap":50},[54,5223,5224,5226,5228,5230,5232,5234,5236,5239,5241,5243,5246,5248,5251],{"class":56,"line":57},[54,5225,87],{"class":86},[54,5227,91],{"class":90},[54,5229,94],{"class":86},[54,5231,875],{"class":90},[54,5233,94],{"class":86},[54,5235,396],{"class":100},[54,5237,5238],{"class":90},", b ",[54,5240,94],{"class":86},[54,5242,892],{"class":100},[54,5244,5245],{"class":90},", c ",[54,5247,94],{"class":86},[54,5249,5250],{"class":100}," 3",[54,5252,273],{"class":90},[54,5254,5255,5257,5259,5261,5263,5265],{"class":56,"line":64},[54,5256,388],{"class":86},[54,5258,2380],{"class":90},[54,5260,820],{"class":86},[54,5262,823],{"class":100},[54,5264,826],{"class":90},[54,5266,829],{"class":86},[54,5268,5269,5272,5274,5277,5279,5281,5284],{"class":56,"line":70},[54,5270,5271],{"class":90},"  t[k ",[54,5273,1662],{"class":86},[54,5275,5276],{"class":134}," \"_new\"",[54,5278,150],{"class":90},[54,5280,94],{"class":86},[54,5282,5283],{"class":90}," t[k]  ",[54,5285,5286],{"class":60},"-- adding keys during iteration — UNDEFINED\n",[54,5288,5289],{"class":56,"line":76},[54,5290,422],{"class":86},[54,5292,5293],{"class":56,"line":83},[54,5294,5295],{"class":60},"-- Some new keys may be visited, some may not. Don't do this.\n",[54,5297,5298],{"class":56,"line":121},[54,5299,80],{"emptyLinePlaceholder":79},[54,5301,5302],{"class":56,"line":141},[54,5303,5304],{"class":60},"-- SAFE: collect keys first, then modify\n",[54,5306,5307,5309,5312,5314],{"class":56,"line":161},[54,5308,87],{"class":86},[54,5310,5311],{"class":90}," keys ",[54,5313,94],{"class":86},[54,5315,383],{"class":90},[54,5317,5318,5320,5322,5324,5326,5328,5330,5333,5335,5338,5340,5342,5344,5346,5348],{"class":56,"line":179},[54,5319,388],{"class":86},[54,5321,2380],{"class":90},[54,5323,820],{"class":86},[54,5325,823],{"class":100},[54,5327,826],{"class":90},[54,5329,3597],{"class":86},[54,5331,5332],{"class":90}," keys[",[54,5334,182],{"class":86},[54,5336,5337],{"class":90},"keys ",[54,5339,1295],{"class":86},[54,5341,396],{"class":100},[54,5343,150],{"class":90},[54,5345,94],{"class":86},[54,5347,2380],{"class":90},[54,5349,422],{"class":86},[54,5351,5352,5354,5357,5359,5361,5364],{"class":56,"line":191},[54,5353,388],{"class":86},[54,5355,5356],{"class":90}," _, k ",[54,5358,820],{"class":86},[54,5360,2345],{"class":100},[54,5362,5363],{"class":90},"(keys) ",[54,5365,829],{"class":86},[54,5367,5368,5370,5372,5374,5376,5378,5380],{"class":56,"line":196},[54,5369,5271],{"class":90},[54,5371,1662],{"class":86},[54,5373,5276],{"class":134},[54,5375,150],{"class":90},[54,5377,94],{"class":86},[54,5379,5283],{"class":90},[54,5381,5382],{"class":60},"-- safe: iterating a separate array\n",[54,5384,5385],{"class":56,"line":202},[54,5386,422],{"class":86},[15,5388,5389,5397],{},[19,5390,5391,5394,5395],{},[32,5392,5393],{},"ipairs"," stops at the first ",[32,5396,315],{},": Not suitable for sparse arrays or tables with intentional nil holes.",[42,5399,5400],{"language":44},[46,5401,5403],{"className":48,"code":5402,"language":44,"meta":50,"style":50},"local t = {1, 2, nil, 4, 5}\nfor i, v in ipairs(t) do print(i, v) end  -- 1 1 \u002F 2 2 (stops at nil at index 3)\n-- Use pairs() to iterate all existing keys, or maintain explicit length\n",[32,5404,5405,5435,5461],{"__ignoreMap":50},[54,5406,5407,5409,5411,5413,5415,5417,5419,5421,5423,5425,5427,5429,5431,5433],{"class":56,"line":57},[54,5408,87],{"class":86},[54,5410,91],{"class":90},[54,5412,94],{"class":86},[54,5414,97],{"class":90},[54,5416,305],{"class":100},[54,5418,104],{"class":90},[54,5420,310],{"class":100},[54,5422,104],{"class":90},[54,5424,315],{"class":100},[54,5426,104],{"class":90},[54,5428,166],{"class":100},[54,5430,104],{"class":90},[54,5432,147],{"class":100},[54,5434,273],{"class":90},[54,5436,5437,5439,5442,5444,5446,5448,5450,5453,5456,5458],{"class":56,"line":64},[54,5438,388],{"class":86},[54,5440,5441],{"class":90}," i, v ",[54,5443,820],{"class":86},[54,5445,2345],{"class":100},[54,5447,826],{"class":90},[54,5449,3597],{"class":86},[54,5451,5452],{"class":100}," print",[54,5454,5455],{"class":90},"(i, v) ",[54,5457,1027],{"class":86},[54,5459,5460],{"class":60},"  -- 1 1 \u002F 2 2 (stops at nil at index 3)\n",[54,5462,5463],{"class":56,"line":70},[54,5464,5465],{"class":60},"-- Use pairs() to iterate all existing keys, or maintain explicit length\n",[15,5467,5468,5471,5472,5474],{},[19,5469,5470],{},"Deep copy with metatables must preserve the metatable",": Forgetting ",[32,5473,5102],{}," breaks OOP after copy.",[37,5476,5478],{"id":5477},"spot-the-bug","🧠 Spot the Bug",[42,5480,5481,5665],{"language":44},[46,5482,5484],{"className":48,"code":5483,"language":44,"meta":50,"style":50},"local Base = {}\nBase.__index = Base\nfunction Base.new() return setmetatable({x = 1}, Base) end\nfunction Base:get() return self.x end\n\nlocal Derived = setmetatable({}, {__index = Base})\nDerived.__index = Derived\nfunction Derived.new() return setmetatable({y = 2}, Derived) end\n\nlocal d = Derived.new()\nprint(d:get(), d.y)\n",[32,5485,5486,5497,5509,5538,5561,5565,5583,5595,5624,5628,5644],{"__ignoreMap":50},[54,5487,5488,5490,5493,5495],{"class":56,"line":57},[54,5489,87],{"class":86},[54,5491,5492],{"class":90}," Base ",[54,5494,94],{"class":86},[54,5496,383],{"class":90},[54,5498,5499,5502,5504,5506],{"class":56,"line":64},[54,5500,5501],{"class":90},"Base.",[54,5503,34],{"class":127},[54,5505,131],{"class":86},[54,5507,5508],{"class":90}," Base\n",[54,5510,5511,5513,5516,5518,5520,5522,5524,5526,5529,5531,5533,5536],{"class":56,"line":70},[54,5512,1556],{"class":86},[54,5514,5515],{"class":127}," Base",[54,5517,931],{"class":90},[54,5519,1564],{"class":127},[54,5521,3594],{"class":90},[54,5523,3431],{"class":86},[54,5525,1131],{"class":100},[54,5527,5528],{"class":90},"({x ",[54,5530,94],{"class":86},[54,5532,396],{"class":100},[54,5534,5535],{"class":90},"}, Base) ",[54,5537,422],{"class":86},[54,5539,5540,5542,5544,5546,5549,5551,5553,5555,5557,5559],{"class":56,"line":76},[54,5541,1556],{"class":86},[54,5543,5515],{"class":127},[54,5545,1638],{"class":90},[54,5547,5548],{"class":127},"get",[54,5550,3594],{"class":90},[54,5552,3431],{"class":86},[54,5554,1579],{"class":100},[54,5556,931],{"class":90},[54,5558,563],{"class":127},[54,5560,3092],{"class":86},[54,5562,5563],{"class":56,"line":83},[54,5564,80],{"emptyLinePlaceholder":79},[54,5566,5567,5569,5572,5574,5576,5578,5580],{"class":56,"line":121},[54,5568,87],{"class":86},[54,5570,5571],{"class":90}," Derived ",[54,5573,94],{"class":86},[54,5575,1131],{"class":100},[54,5577,1838],{"class":90},[54,5579,94],{"class":86},[54,5581,5582],{"class":90}," Base})\n",[54,5584,5585,5588,5590,5592],{"class":56,"line":141},[54,5586,5587],{"class":90},"Derived.",[54,5589,34],{"class":127},[54,5591,131],{"class":86},[54,5593,5594],{"class":90}," Derived\n",[54,5596,5597,5599,5602,5604,5606,5608,5610,5612,5615,5617,5619,5622],{"class":56,"line":161},[54,5598,1556],{"class":86},[54,5600,5601],{"class":127}," Derived",[54,5603,931],{"class":90},[54,5605,1564],{"class":127},[54,5607,3594],{"class":90},[54,5609,3431],{"class":86},[54,5611,1131],{"class":100},[54,5613,5614],{"class":90},"({y ",[54,5616,94],{"class":86},[54,5618,892],{"class":100},[54,5620,5621],{"class":90},"}, Derived) ",[54,5623,422],{"class":86},[54,5625,5626],{"class":56,"line":179},[54,5627,80],{"emptyLinePlaceholder":79},[54,5629,5630,5632,5635,5637,5640,5642],{"class":56,"line":191},[54,5631,87],{"class":86},[54,5633,5634],{"class":90}," d ",[54,5636,94],{"class":86},[54,5638,5639],{"class":90}," Derived.",[54,5641,1564],{"class":100},[54,5643,1435],{"class":90},[54,5645,5646,5648,5650,5653,5655,5657,5660,5663],{"class":56,"line":196},[54,5647,573],{"class":100},[54,5649,492],{"class":90},[54,5651,5652],{"class":127},"d",[54,5654,1638],{"class":90},[54,5656,5548],{"class":100},[54,5658,5659],{"class":90},"(), d.",[54,5661,5662],{"class":127},"y",[54,5664,1745],{"class":90},[5666,5667,5668,5672,5678,5717,5743,5761,5829],"details",{},[5669,5670,5671],"summary",{},"Answer",[15,5673,5674,5675,931],{},"Prints ",[32,5676,5677],{},"1 2",[5679,5680,5681],"ul",{},[5682,5683,5684,5687,5688,5691,5692,5687,5695,5691,5698,5687,5701,5687,5704,5707,5708,5687,5711,5687,5714,5716],"li",{},[32,5685,5686],{},"d:get()"," → ",[32,5689,5690],{},"d.get"," not found → ",[32,5693,5694],{},"__index = Derived",[32,5696,5697],{},"Derived.get",[32,5699,5700],{},"Derived.__index",[32,5702,5703],{},"{__index = Base}",[32,5705,5706],{},"Base.get"," found → called with ",[32,5709,5710],{},"self = d",[32,5712,5713],{},"d.x",[32,5715,305],{}," (x set by... wait, Base.new was NOT called).",[15,5718,5719,5720,5723,5724,5727,5728,5731,5732,5735,5736,5687,5738,5687,5741,931],{},"Actually: ",[32,5721,5722],{},"Derived.new()"," returns ",[32,5725,5726],{},"setmetatable({y = 2}, Derived)",". The table only has ",[32,5729,5730],{},"y = 2",", not ",[32,5733,5734],{},"x = 1",". So ",[32,5737,5686],{},[32,5739,5740],{},"self.x",[32,5742,315],{},[15,5744,5745,5746,5749,5750,5753,5754,5757,5758,5760],{},"The output is ",[32,5747,5748],{},"nil 2",". The bug: ",[32,5751,5752],{},"Derived.new"," doesn't call ",[32,5755,5756],{},"Base.new()",", so ",[32,5759,563],{}," is never set. Fix:",[46,5762,5764],{"className":48,"code":5763,"language":44,"meta":50,"style":50},"function Derived.new()\n  local self = Base.new()  -- set x = 1\n  self.y = 2\n  return setmetatable(self, Derived)  -- override metatable\nend\n",[32,5765,5766,5778,5796,5809,5825],{"__ignoreMap":50},[54,5767,5768,5770,5772,5774,5776],{"class":56,"line":57},[54,5769,1556],{"class":86},[54,5771,5601],{"class":127},[54,5773,931],{"class":90},[54,5775,1564],{"class":127},[54,5777,1435],{"class":90},[54,5779,5780,5782,5784,5786,5789,5791,5793],{"class":56,"line":64},[54,5781,802],{"class":86},[54,5783,1579],{"class":100},[54,5785,131],{"class":86},[54,5787,5788],{"class":90}," Base.",[54,5790,1564],{"class":100},[54,5792,1442],{"class":90},[54,5794,5795],{"class":60},"-- set x = 1\n",[54,5797,5798,5800,5802,5804,5806],{"class":56,"line":70},[54,5799,1591],{"class":100},[54,5801,931],{"class":90},[54,5803,5662],{"class":127},[54,5805,131],{"class":86},[54,5807,5808],{"class":100}," 2\n",[54,5810,5811,5813,5815,5817,5819,5822],{"class":56,"line":76},[54,5812,852],{"class":86},[54,5814,1131],{"class":100},[54,5816,492],{"class":90},[54,5818,1174],{"class":100},[54,5820,5821],{"class":90},", Derived)  ",[54,5823,5824],{"class":60},"-- override metatable\n",[54,5826,5827],{"class":56,"line":83},[54,5828,422],{"class":86},[15,5830,5831,5832,5723,5834,5836,5837,5723,5840,931],{},"Now ",[32,5833,5686],{},[32,5835,305],{}," and ",[32,5838,5839],{},"d.y",[32,5841,310],{},[5843,5844,5845],"style",{},"html pre.shiki code .sdCPZ, html code.shiki .sdCPZ{--shiki-default:#6A737D;--shiki-github-dark:#6A737D}html pre.shiki code .svdQ7, html code.shiki .svdQ7{--shiki-default:#D73A49;--shiki-github-dark:#F97583}html pre.shiki code .ssxIu, html code.shiki .ssxIu{--shiki-default:#24292E;--shiki-github-dark:#E1E4E8}html pre.shiki code .snvgF, html code.shiki .snvgF{--shiki-default:#005CC5;--shiki-github-dark:#79B8FF}html pre.shiki code .sIsaT, html code.shiki .sIsaT{--shiki-default:#6F42C1;--shiki-github-dark:#B392F0}html pre.shiki code .sJ6F3, html code.shiki .sJ6F3{--shiki-default:#032F62;--shiki-github-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}html.github-dark .shiki span {color: var(--shiki-github-dark);background: var(--shiki-github-dark-bg);font-style: var(--shiki-github-dark-font-style);font-weight: var(--shiki-github-dark-font-weight);text-decoration: var(--shiki-github-dark-text-decoration);}",{"title":50,"searchDepth":64,"depth":64,"links":5847},[5848,5851,5852,5853,5854],{"id":39,"depth":64,"text":40,"children":5849},[5850],{"id":340,"depth":70,"text":341},{"id":509,"depth":64,"text":510},{"id":1508,"depth":64,"text":1509},{"id":5148,"depth":64,"text":5149},{"id":5477,"depth":64,"text":5478},"[object Object]","md",{},"\u002Flua\u002F05-tables-and-objects",{"title":5,"description":5860},{"Deep-dive into Lua's unified table model":5861},"array\u002Fhash part internals, reference vs value semantics, shallow vs deep copy, OOP via metatables with inheritance and mixins, and production data structures (linked list, ring buffer, object pool, observer pattern).","lua\u002F05-tables-and-objects","MW3zJig8k7qbgsiyaR43T8FknMvMBXOAeV_0p9iFvms",1789924650305]