| Earlier, since the function was a 3.x function it was important to handle undef the same way as an empty string because empty strings were considered to be equivalent to undef - it was just a mess. Now with data types and automatic type checking there should be a lot less confusion over what something is - and treating undef as "an empty container" is far more likely to mask a bug than being useful. So, what to use instead of using empty() or !empty() to check if something is/not-is undef depends on why that check is made. Also, if the check is made to raise an error, the entire construct can be replaced by using either automatic type checking, or calling assert_type. Examples for checking if something is:
- undef: $x =~ Undef, or $x == undef
- not undef: $x =~ NotUndef, $x !~ Undef, or $x != undef
- undef or an empty string: $x =~ Optional[String[0,0]]
- non-empty string: $x =~ String[1]
- non-empty array: $x =~ Array[1]
- non-empty hash: $x =~ Hash[1]
- non-empty array or hash: $x =~ Collection[1]
- the same as stdlib 3.x version of empty: $x =~ Variant[String[0,0], Collection[0,0], Undef]
If using empty() to mean "unspecified" and having it in multiple places in a module, it could be of value to define a data type - say MyModule::Unspecified like this:
type MyModule::Unspecified = Variant\[String\[0,0], Collection\[0,0], Undef]
|
and then replace empty($x) with $x =~ MyModule::Unspecified Or, if so preferred, define a function like this:
function mymodule::unspecified(Any $x) { |
$x =~ Variant\[String\[0,0], Collection\[0,0], Undef] |
}
|
and use it instead of empty(). |