To jest moje pierwsze pytanie do tej niesamowitej społeczności.Lua: Ustawienie metameth nie działa tak, jak chcę
W tych dniach piszę moduł Lua dla siebie. Tutaj jest to minimalna część kodu z problemem
mt = {}
bf = {}
------------
-- bf.new --
------------
function bf.new(A)
local out = A
setmetatable(out,mt)
return out
end
-----------------
-- bf.tostring --
-----------------
function bf.tostring(A)
local typeA = type(A)
local out = ""
if typeA=="number" or typeA=="boolean" then
print(tostring(A))
elseif typeA=="table" then
local col = ""
local m = #A
local typeA1 = type(A[1])
for i=1,m do
if typeA1=="table" then
n = #A[1]
for j=1,n do
out = out.." "..tostring(A[i][j])
if j==n then
out = out.."\n"
end
end
elseif (typeA1=="number" or typeA1=="boolean") then
row = row.." "..tostring(A[i][j])
end
end
end
return out
end
-----------------------------
-- bf.compare(A,logical,B) --
-----------------------------
function bf.compare(A,logical,B)
if (logical~="<" and
logical~=">" and
logical~="<=" and
logical~=">=" and
logical~="==" and
logical~="~=") then
error("second input input must be a logical operator written into a string")
end
local out = {}
local ind = {}
local count = 0
if type(B)=="number" then
if type(A[1])=="table" then
for i=1,#A do
out[i] = {}
for j=1,#A[1] do
loadstring("cond ="..A[i][j]..logical..B)()
if cond then
out[i][j] = true
count = count+1
ind[count] = (i-1)*#A[1]+j
else
out[i][j] = false
end
end
end
elseif type(A[1])=="number" then
for j=1,#A do
loadstring("cond ="..A[j]..logical..B)()
if cond then
out[j] = true
count = count+1
ind[count] = j
else
out[j] = false
end
end
end
else
if (type(A[1])=="table" and type(B[1])=="table") then
if (#A==#B and #A[1]==#B[1]) then
for i=1,#A do
out[i] = {}
for j=1,#A[1] do
loadstring("cond ="..A[i][j]..logical..B[i][j])()
if cond then
out[i][j] = true
count = count+1
ind[count] = (i-1)*#A[1]+j
else
out[i][j] = false
end
end
end
else
error("The comparison can be done between "..
"two matrix with same dimension "..
"or between a matrix with a scalar value")
end
elseif (type(A[1])=="number" and type(B[1])=="number") then
if (#A==#B) then
for j=1,#A do
loadstring("cond ="..A[j]..logical..B[j])()
if cond then
out[j] = true
count = count+1
ind[count] = j
else
out[j] = false
end
end
else
error("Comparison between "..
"two vector with different dimension")
end
else
error("The comparison can be done between "..
"two matrix with same dimension "..
"or between a matrix with a scalar value")
end
end
return setmetatable(out,mt)--,ind
end
------------------------
-- metamethod setting --
------------------------
mt.__tostring = bf.tostring
mt.__lt = function(A,B) return bf.compare(A,"<",B) end
--------------------------
-- use of my metamethod --
--------------------------
A = bf.new{{1,2,3,4},{5,6,7,8},{9,10,11,12}}
B = bf.new{{3,6,1,8},{1,3,87,20},{11,2,5,7}}
C1 = bf.compare(A,"<",B)
C2 = A<B
print("What I want")
print(C1)
print("What I get")
print(C2)
Jeśli prowadzisz ten mały skrypt, można zobaczyć, że kiedy używam bf.compare funkcji bezpośrednio Mam to, czego potrzebuję. Kiedy używam BF.compare przez metametod, daje mi to tylko "skalarną" wartość true.
Jakieś sugestie?
EDIT
Tutaj jest wyjście:
What I want
true true false true
false false true true
true false false false
What I get
true
>Exit code: 0
Naprawdę nie widzę tego w ogóle, ponieważ nie wyświetla się wyników. – Puppy
+1 za podanie działającego kodu. – jpjacobs