これに入る前に、左端の演算子で行う特別な操作には、追加の操作を使用することを強くお勧めします。__unm
または__len
単項であるため、明らかな選択肢になります。たとえば、ステートメントは次のようになります
local x = -(a .. b .. c)
そうしないと、連結操作が代用できず、デフォルトの演算子の結合性も失われるため、これによりコードをより適切に追跡できます..
。つまり、意図した操作では、これらの方程式が真になります。
a .. b .. c ~= a .. (b .. c)
(a .. b ) .. c ~= a .. (b .. c)
そうは言っても、Luaで左端の操作を検出できるとは思いません-少なくとも割り当ての前ですが、右端の操作を検出することはできます。
意図したとおりに記述していないため、おそらく操作を変更して、最も右側の操作を別の方法で処理し、最終的に同じ結果を得ることができることを指摘しておきます。そのため、サンプルコードを次に示します。
local MT = {};
local registry = setmetatable({}, {__mode == "k"});
function MT.__concat(left, right)
if not registry[right] then
print("rightmost operation", left, right);
end
local r = newTT(left.val .. right.val);
registry[r] = true;
return r;
end
function MT:__tostring()
return tostring(self.val);
end
function newTT(v)
return setmetatable({ val = v }, MT);
end
local a = newTT("A");
local b = newTT("B");
local c = newTT("C");
local d = newTT("D");
local x = a .. (b .. c) .. d;
local y = a .. (c .. b) .. d;
local z = a .. b .. x; -- the b .. x op will not be detected as rightmost!
各ティックでレジストリをリセットすることで、最後の行で指摘した問題を回避できる可能性がありますが、実際には、その動作により操作がより予測しやすくなります。または、少なくとも私の目には。
いずれにせよ、そのようなことを行うと、解決するためにかかる労力に見合わない可能性が非常に高い新しい問題が大量に発生することがわかります。