Sitelet https://github.com/lua-stdlib/lua-stdlib/commit/4b6968eca8d3eca409fc800e2d06977a8603e100
Skip to content

Commit 4b6968e

Browse files
committed
string: remove broken pickle implementation.
This implementation is mostly useless. In preparation for something else much cleaner and more functional, delete the cruft for this broken implementation: * lib/std/base.lua (picklable, pickle_vtable, pickle): Remove broken implementation. * lib/std/string.lua (pickle): Remove re-export of std.base.pickle. * lib/std/container.lua (__pickle): Remove. * lib/std/list.lua, lib/std/object.lua, lib/std/set.lua, lib/std/strbuf.lua, lib/std/tree.lua (__pickle): Likewise. * specs/container_spec.yaml, specs/list_spec.yaml, specs/object_spec.yaml, specs/set_spec.yaml, specs/std_spec.yaml, specs/strbuf_spec.yaml, specs/string_spec.yaml, specs/tree_spec.yaml: Adjust accordingly. * NEWS.md: Update. Signed-off-by: Gary V. Vaughan <gary@gnu.org>
1 parent ed4174a commit 4b6968e

17 files changed

Lines changed: 12 additions & 520 deletions

‎NEWS.md‎

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -73,14 +73,6 @@
7373
more legible deeply nested table output, identically to previous
7474
releases.
7575
76-
- `std.string.pickle` uses the more powerful features of the improved
77-
render function to return a `std.eval`able string that recreates an
78-
equivalent object to the original argument more accurately than
79-
before.
80-
81-
- All of stdlib's object prototypes now provide a `__pickle` metamethod,
82-
which makes them picklable with `std.string.pickle` too!
83-
8476
- `std.npairs` and `std.rnpairs` now respect `__len` metamethod, if any.
8577
8678
- We used to have an object module method, `std.object.type`, which
@@ -110,8 +102,6 @@
110102

111103
### Bug fixes
112104

113-
- `std.string.pickle` works with nested tables, and mutable keys.
114-
115105
- `std.string.wrap` doesn't throw a StrBuf deprecation warning any more.
116106
117107
- `std.getmetamethod` now returns functable valued metamethods

‎lib/std/base.lua‎

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -387,57 +387,6 @@ local function sortkeys (t)
387387
end
388388

389389

390-
local picklable = {
391-
boolean = true, ["nil"] = true, number = true, string = true,
392-
}
393-
394-
local pickle_vtable = {
395-
term = function (x)
396-
local type_x = type (x)
397-
if picklable[type_x] or getmetamethod (x, "__pickle") then
398-
return true
399-
elseif type (x) ~= "table" then
400-
-- don't know what to do with this :(
401-
error ("cannot pickle " .. tostring (x))
402-
end
403-
end,
404-
405-
elem = function (x)
406-
-- math
407-
if x ~= x then
408-
return "0/0"
409-
elseif x == math_huge then
410-
return "math.huge"
411-
elseif x == -math_huge then
412-
return "-math.huge"
413-
elseif x == nil then
414-
return "nil"
415-
end
416-
417-
-- common types
418-
local type_x = type (x)
419-
if type_x == "string" then
420-
return string_format ("%q", x)
421-
elseif type_x == "number" or type_x == "boolean" then
422-
return tostring (x)
423-
end
424-
425-
-- pickling metamethod
426-
local __pickle = getmetamethod (x, "__pickle")
427-
if __pickle then return __pickle (x) end
428-
end,
429-
430-
pair = function (x, kp, vp, k, v, kstr, vstr)
431-
return "[" .. kstr .. "]=" .. vstr
432-
end,
433-
}
434-
435-
436-
local function pickle (x)
437-
return render (x, pickle_vtable)
438-
end
439-
440-
441390
local function ripairs (t)
442391
local oob = 1
443392
while t[oob] ~= nil do
@@ -603,7 +552,6 @@ return {
603552

604553
string = {
605554
escape_pattern = escape_pattern,
606-
pickle = pickle,
607555
render = render,
608556
split = split,
609557
},

‎lib/std/container.lua‎

Lines changed: 2 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@ local select = select
3535
local setmetatable = setmetatable
3636
local type = type
3737

38-
local string_find = string.find
39-
local string_sub = string.sub
4038
local table_concat = table.concat
4139

4240

@@ -50,7 +48,6 @@ local Module = _.std.object.Module
5048
local _DEBUG = _.debug_init._DEBUG
5149
local copy = _.std.base.copy
5250
local mapfields = _.std.object.mapfields
53-
local pickle = _.std.string.pickle
5451
local render = _.std.string.render
5552
local sortkeys = _.std.base.sortkeys
5653

@@ -156,8 +153,7 @@ local tostring_vtable = {
156153
-- local g = Graph { "node1", "node2" }
157154
-- assert (nodes (g) == 2)
158155
local prototype = {
159-
_module = "std.container", -- for pickle()
160-
_type = "Container", -- for tostring() and type()
156+
_type = "Container",
161157

162158
--- Metamethods
163159
-- @section metamethods
@@ -216,16 +212,6 @@ local prototype = {
216212

217213
-- If a metatable was set, then merge our fields and use it.
218214
if next (getmetatable (obj) or {}) then
219-
local new_mt = getmetatable (obj)
220-
local new_type = new_mt._type or ""
221-
local i = string_find ("." .. new_type, "%.[^%.]*$")
222-
if i > 1 then
223-
-- expand long-form type.
224-
new_mt._type = string_sub (new_type, i)
225-
new_mt._module = string_sub (new_type, 1, i -2)
226-
end
227-
228-
-- Merge fields.
229215
obj_mt = instantiate (mt, getmetatable (obj))
230216

231217
-- Merge object methods.
@@ -234,11 +220,6 @@ local prototype = {
234220
then
235221
obj_mt.__index = instantiate (mt.__index, obj_mt.__index)
236222
end
237-
238-
-- Invalidate obsoleted _module field
239-
if new_mt._type ~= nil and new_mt._module == nil then
240-
obj_mt._module = nil
241-
end
242223
end
243224

244225
return setmetatable (obj, obj_mt)
@@ -262,42 +243,7 @@ local prototype = {
262243
return table_concat {
263244
-- Pass a shallow copy to render to avoid triggering __tostring
264245
-- again and blowing the stack.
265-
getmetatable (self)._type,
266-
" ",
267-
render (copy (self), tostring_vtable),
268-
}
269-
end,
270-
271-
272-
--- Return a loadable serialization of this object, where possible.
273-
--
274-
-- If the object contains an unpicklable element (e.g. a userdata with
275-
-- no `__pickle` metamethod) then neither is the entire container
276-
-- picklable, and an error will be raised.
277-
--
278-
-- Assuming the object metatable carries a correct `_module` field,
279-
-- (either set manually when the prototype was created, or else because
280-
-- the long form `_type` field was provided) that module path will be
281-
-- required when the pickled object is evaluated. Otherwise, the bare
282-
-- `_type` string is used and you will be responsible for setting that
283-
-- to the correct object prototype before evaluating a pickled object.
284-
-- @function prototype:__pickle
285-
-- @treturn string pickled object representation
286-
-- @see std.string.pickle
287-
__pickle = function (self)
288-
local mt = getmetatable (self)
289-
if type (mt._module) == "string" then
290-
-- object with _module set
291-
return table_concat {
292-
'require "',
293-
mt._module,
294-
'".prototype ',
295-
pickle (copy (self)),
296-
}
297-
end
298-
-- rely on caller preloading `local ObjectName = require "obj".prototype`
299-
return table_concat {
300-
mt._type, " ", pickle (copy (self)),
246+
getmetatable (self)._type, " ", render (copy (self), tostring_vtable),
301247
}
302248
end,
303249
}

‎lib/std/list.lua‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ local methods = {
208208
-- local List = require "std.list".prototype
209209
-- assert (std.type (List) == "List")
210210
List = Object {
211-
_type = "std.list.List",
211+
_type = "List",
212212

213213
--- Metamethods
214214
-- @section metamethods

‎lib/std/object.lua‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ local methods = {
138138
-- command = pipeline[pid], -- manual assignment
139139
-- }
140140
local prototype = Container {
141-
_type = "std.object.Object",
141+
_type = "Object",
142142

143143
--- Metamethods
144144
-- @section metamethods

‎lib/std/set.lua‎

Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ end
194194
-- local Set = require "std.set".prototype
195195
-- assert (std.type (Set) == "Set")
196196
prototype = Container {
197-
_type = "std.set.Set",
197+
_type = "Set",
198198

199199
--- Set object initialisation.
200200
--
@@ -288,32 +288,6 @@ prototype = Container {
288288
table_sort (keys)
289289
return getmetatable (self)._type .. " {" .. table_concat (keys, ", ") .. "}"
290290
end,
291-
292-
--- Return a loadable serialization of this object, where possible.
293-
-- @function prototype:__pickle
294-
-- @treturn string pickled object representation
295-
-- @see std.string.pickle
296-
__pickle = function (self)
297-
local mt, keys = getmetatable (self), {}
298-
for k in _pairs (self) do
299-
keys[#keys + 1] = pickle (k)
300-
end
301-
table_sort (keys)
302-
if type (mt._module) == "string" then
303-
-- object with _module set
304-
return table_concat {
305-
'require "',
306-
mt._module,
307-
'".prototype {',
308-
table_concat (keys, ","),
309-
"}",
310-
}
311-
end
312-
-- rely on caller preloading `local ObjName = require "module".prototype`
313-
return table_concat {
314-
mt._type, " {", table_concat (keys, ","), "}"
315-
}
316-
end,
317291
}
318292

319293

‎lib/std/strbuf.lua‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ local methods = {
133133

134134
return Module {
135135
prototype = Object {
136-
_type = "std.strbuf.StrBuf",
136+
_type = "StrBuf",
137137

138138
--- Metamethods
139139
-- @section metamethods

‎lib/std/string.lua‎

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ local copy = _.std.base.copy
4040
local escape_pattern = _.std.string.escape_pattern
4141
local len = _.std.operator.len
4242
local merge = _.std.base.merge
43-
local pickle = _.std.string.pickle
4443
local render = _.std.string.render
4544
local sortkeys = _.std.base.sortkeys
4645
local split = _.std.string.split
@@ -413,19 +412,6 @@ M = {
413412
-- @usage print (pad (trim (outputstr, 78)) .. "\n")
414413
pad = X ("pad (string, int, ?string)", pad),
415414

416-
--- Convert a value to a string.
417-
-- The string can be passed to `std.eval` to retrieve the value.
418-
-- Only primitives for which `tostring` returns an evalable result,
419-
-- and objects with a `__pickle` metamethod are picklable.
420-
-- @function pickle
421-
-- @param x object to pickle
422-
-- @treturn string reversible string rendering of *x*
423-
-- @see std.eval
424-
-- @usage
425-
-- freeze = std.functional.memoize (pickle)
426-
-- thaw = function (x) return std.eval (x) end
427-
pickle = X ("pickle (?any)", pickle),
428-
429415
--- Pretty-print a table, or other object.
430416
-- @function prettytostring
431417
-- @param x object to convert to string

‎lib/std/tree.lua‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ end
234234
-- io.write (leaf .. "\t")
235235
-- end
236236
prototype = Container {
237-
_type = "std.tree.Tree",
237+
_type = "Tree",
238238

239239
--- Metamethods
240240
-- @section metamethods

‎specs/container_spec.yaml‎

Lines changed: 3 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -53,22 +53,15 @@ specify std.container:
5353
things = Container {foo="bar", _baz="quux"}
5454
expect (getmetatable (things)).not_to_be (getmetatable (Container))
5555
expect (getmetatable (things)._baz).to_be "quux"
56-
- it propagates '_type' and '_module' fields:
56+
- it propagates '_type' field:
5757
things = Container {1}
5858
u, v = things {"u"}, things {"v"}
5959
expect (objtype (u)).to_be "Container"
60-
expect (getmetatable (u)._module).to_be "std.container"
6160
expect (objtype (v)).to_be (objtype (Container))
62-
expect (getmetatable (v)._module).
63-
to_be (getmetatable (Container)._module)
64-
- it sets '_type' and '_module' from long prototype '_type' field:
65-
things = Container {_type = "specs.example.Things"}
66-
expect (objtype (things)).to_be "Things"
67-
expect (getmetatable (things)._module).to_be "specs.example"
6861
- context with module functions:
6962
- before:
7063
Bag = require "std.base".object.Module {
71-
prototype = Container { _type = "Bag", _module = "specs.example" },
64+
prototype = Container { _type = "Bag" },
7265
count = function (bag)
7366
local n = 0
7467
for _, m in pairs (bag) do n = n + m end
@@ -90,18 +83,11 @@ specify std.container:
9083
- it does allow elements named after module functions:
9184
things = Bag { count = 1337 }
9285
expect (Bag.count (things)).to_be (1337)
93-
- it propagates '_type' and '_module' fields:
86+
- it propagates '_type' field:
9487
things = Bag { bananas=0 }
9588
u, v = things { bananas=1 }, things { coconuts=0 }
9689
expect (objtype (u)).to_be "Bag"
97-
expect (getmetatable (u)._module).to_be "specs.example"
9890
expect (objtype (v)).to_be (objtype (Bag.prototype))
99-
expect (getmetatable (v)._module).
100-
to_be (getmetatable (Bag.prototype)._module)
101-
- it sets '_type' and '_module' from long prototype '_type' field:
102-
things = Bag {_type = "specs.example.Things"}
103-
expect (objtype (things)).to_be "Things"
104-
expect (getmetatable (things)._module).to_be "specs.example"
10591

10692

10793
- describe field access:
@@ -143,50 +129,3 @@ specify std.container:
143129
not_to_contain ";"
144130
expect (tostring (things {one = true, two = true, three = true})).
145131
to_contain ";"
146-
147-
148-
- describe __pickle:
149-
- before:
150-
loadstring = loadstring or load
151-
function unpickle (s) return loadstring ("return " .. s) () end
152-
f = require "std.string".pickle
153-
154-
Derived = Container {_type = "Derived"}
155-
things = Derived {one="two", "three"}
156-
157-
- it returns a string:
158-
expect (type (f (things))).to_be "string"
159-
- it resets '_module' metafield when '_type' changes:
160-
expect (getmetatable (things)._module).to_be (nil)
161-
- it supports setting '_module' and '_type' metafields:
162-
Everything = Derived { _type = "Everything", _module = "nearly" }
163-
expect (objtype (Everything)).to_be "Everything"
164-
expect (getmetatable (Everything)._module).to_be "nearly"
165-
Everything = Container { _type = "Everything", _module = "nearly" }
166-
expect (objtype (Everything)).to_be "Everything"
167-
expect (getmetatable (Everything)._module).to_be "nearly"
168-
- it does not have a period in '_type':
169-
Period = Derived { _type = "specs.example.Period" }
170-
expect (string.find (type (Period), "%.")).to_be (nil)
171-
- it propagates the '_module' metafield when '_type' is unchanged:
172-
expect (getmetatable (Container {1})._module).
173-
to_be (getmetatable (Container)._module)
174-
- context with '_module' metafield:
175-
- it requires the module path for later invocation:
176-
expect (f (Container)).to_be 'require "std.container".prototype {}'
177-
- it roundtrips objects:
178-
expect (unpickle (f (Container))).to_equal (Container)
179-
- context with '_type' metafield only:
180-
- it uses the '_type' value for later invocation:
181-
expect (f (things)).to_be 'Derived {[1]="three",["one"]="two"}'
182-
- it roundtrips objects:
183-
compat = require "specl.compat"
184-
compat.setfenv (unpickle, compat.getfenv (1))
185-
expect (unpickle (f (things))).to_equal (things)
186-
- it converts a nested object to a representative string:
187-
container = Container {Derived {"?"}, ["!"]=42}
188-
expect (f (container)).
189-
to_be 'require "std.container".prototype {[1]=Derived {[1]="?"},["!"]=42}'
190-
- it roundtrips nested objects:
191-
container = Container {Derived {"?"}, ["!"]=42}
192-
expect (unpickle (f (container))).to_equal (container)

0 commit comments

Comments
 (0)