Lua 重载时确定最左边的操作数

Lua 重载时确定最左边的操作数,lua,Lua,在内部重载右关联运算符时,是否可以确定最左边的操作数?类似的东西 MyClass.__concat(left, right) if is_leftmost_operand(left) then -- do stuffs else -- do other stuffs end end 在这里,您可以像平常一样调用add,而不设置任何标志或其他内容 instance1..instance2..instance3 我想要\uuu concat的正确关联行为,但我希望在链

在内部重载右关联运算符时,是否可以确定最左边的操作数?类似的东西

MyClass.__concat(left, right)
  if is_leftmost_operand(left) then
    -- do stuffs
  else
    -- do other stuffs
  end
end
在这里,您可以像平常一样调用add,而不设置任何标志或其他内容

instance1..instance2..instance3
我想要
\uuu concat
的正确关联行为,但我希望在链的开头发生一些不同的事情

编辑:

为了澄清,在下面的表达式中,
instance1
instance3
都将被视为最左边的操作数

instance1..instance2..(instance3..instance4..instance5)

在讨论这个问题之前,我强烈建议对最左边的操作符使用额外的操作
\uu unm
\uu 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!
您可能可以通过在每个刻度上重置注册表来解决我在最后一行中指出的问题,但实际上这种行为会使操作更可预测。至少在我眼里是这样


不管怎样,你可以看到做这些事情会带来一大堆新问题,这些问题很可能不值得他们去解决。

在表达式
a..b..e(c..d..e)
?@EgorSkriptunoff是的,a和c都应该是,如果不修改Lua源,就无法区分最左边的操作数。使用
-
手动标记最左边的运算符是个好主意。不需要额外的括号:在
-a..b..c
中,对象
a
将在连接之前转换为标记对象
-a
,这是可以的。
-a..b..c
将与
-a..b..c
相同。因为我的意图是在所有连接操作之后对结果对象执行操作,因为我认为这很可能是OP想要做的。。。毫无疑问,你的变体也会起作用。