I have this assignment from the official book about lua: Exercise 16.1: Frequently, it is useful to add some prefix to a chunk of code when loading it. (We saw an example previously in this chapter, where we prefixed a return to an expression being loaded.) Write a function loadwithprefix that works like load, except that it adds its extra first argument (a string) as a prefix to the chunk being loaded. Like the original load, loadwithprefix should accept chunks represented both as strings and as reader functions. Even in the case that the original chunk is a string, loadwithprefix should not actually concatenate the prefix with the chunk. Instead, it should call load with a proper reader function that first returns the prefix and then returns the original chunk.
function loadwithprefix(prefix, chunk)
local prefixflg = true
return function(...)
local x = select(1, ...)
local env = { x = x, __index = { _G = _G } }
if not prfxflg then
prfxflg = true
return load(prefix, nil, nil, env)
else
return load(' return ' .. code(), nil, nil, env)
end
end
end
local line = io .read()
local f = loadwithprefix('local x = ...; return x ', function(...) return line end)
for i = 1, 10 do
print(string.rep('*', f(i)()))
end
I get : bad argument #2 to 'rep' (number expected, got nil) meaning i cannot evaluate the local x = ...; return x to actually return 1 from the for-loop statement. Any suggestion?
Your
loadwithprefiximplementation is incorrect:You return a function. This is not what you should be doing. You should be calling load with a function, not returning a function which calls load.
That function also doesn't make much sense: The first time it is called, it loads just the prefix, and returns the resulting function. The second time, it returns the first value returned by
chunk- not a function, ifchunkis a proper "reader". It also fails to account forchunkbeing a string.Your testing code also has a minor flaw:
f(i)()should be justf(i)ifloadwithprefixwas implemented correctly. (I also can't make much sense of the prefix. Do you want your suffixes to be something like+ 42?)Here's how I would implement
loadwithprefix:The
...is to passmodeandenvarguments (and whatever else might be added in the future) through.