Closed goldenstein64 closed 3 years ago
This would most likely require a new transformer explicitly for a value to return itself, so the flag can be about whether there is an implicit or explicit "return self" transformer.
In its current state, the resulting behavior would require the programmer to be exceedingly verbose in their code, e.g:
Implicit set:
local some = {
constant = "SOME CONSTANT".
shared = Copy:BehaveAs("set", {})
}
function some.greet()
print("hello")
end
Copy.Flags.ExplicitSet = false
expect(function()
Copy(some)
end).to.never.throw()
Explicit set:
local some = {
constant = Copy:BehaveAs("set", "SOME CONSTANT"),
shared = Copy:BehaveAs("set", {})
}
function some.greet()
print("hello")
end
some.greet = Copy:BehaveAs("set", some.greet)
Copy.Flags.ExplicitSet = true
expect(function()
Copy(some)
end).to.never.throw()
With some changes to Copy.GlobalContext
(by automatically including "set"
as the last handler), this is acceptable.
Of course this could be an XY problem - I want to include this so that there is better or more typechecking in place, but it feels pretty unnecessary for some reason...
A pro to this method is it's more obvious when a value can or cannot be handled, e.g. a behavior of {}
would mean any value with that behavior can't be copied at all and will error.
A con is that this behavior doesn't seem desirable. If this were the case, why would you ever want to use {}
? If something can't be copied, it feels pretty obvious that the only other option is to return itself.
I guess the decision here is, should I choose clarity or simplicity?
They're often on opposite sides of the spectrum, and I really need both.
I think I'll go with simplicity for now, it feels pretty intuitive for {}
to return itself and therefore not do any copying.
If a given value isn't compatible with the given transformer, it can throw an error.
e.g.
Purely optional, a flag should be made for it.
If no transformer matches among multiple, it should throw an error as well.