Yeah, that works to suppress the warning. Itís still an unnecessary hoop to jump through though, and Iím not keen on unnecessary side effects, even if they are usually transparent. (F.ex., what if this is a tied scalar?)
It also loses the distinction between undef and an empty string, should that be needed.
Compared to the alternative length behaviour, it does remove the need for checking definedness of the return value if itís needed in calculations, but you can simply apply your approach to the return value instead then: $len += 0; And that avoids the problem with side effects, as the return value of length is never overloaded.
I hadnít considered this particular point, but as I said, any way the matter is turned, I cannot find a reason to prefer the currently implemented behaviour.
Library modules should not in general export built-in names like open or chdir as part of their default @EXPORT list, because these may sneak into someone elseís namespace and change the semantics unexpectedly. Instead, if the module adds that name to @EXPORT_OK, then itís possible for a user to import the name explicitly, but not implicitly. That is, they could say
use Module 'open';
and it would import the open override. But if they said
they would get the default imports without overrides.
The foregoing mechanism for overriding built-in is restricted, quite deliberately, to the package that requests the import. There is a second method that is sometimes applicable when you wish to override a built-in everywhere, without regard to namespace boundaries. This is achieved by importing a sub into the special namespace CORE::GLOBAL::.