p5pclub / ref-util

Ref::Util - Utility functions for checking references
6 stars 11 forks source link

[RFE] add coercion functions #43

Open robrwo opened 6 years ago

robrwo commented 6 years ago

A common idiom is

is_arrayref($x) ? $x : [$x]

so it would be useful to have coerce_arrayref functions. Probably something equivalent to

sub coerce_arrayref {
  my $x = shift // [];
  is_arrayref($x) ? $x : [$x]
}

A corresponding coerce_hashref would need a bit more thought, since it's not clear what to do about different data types. Maybe something like

sub coerce_hashref {
  my $x = shift // {};
  is_hashref($x) ? $x : { @{ coerce_arrayref($x) } };
}
robrwo commented 6 years ago

These could be grouped in a :coerce export group.

xsawyerx commented 6 years ago

I've never written this idiom before. How common is this? When is the situation you use it?

It seems like you're assuming it's either an arrayref or - whatever it is - you could just stick it in an arrayref. I cannot come up with a situation off-hand where this is my assumption.

robrwo commented 6 years ago

Well, the more common version is actually

(ref($x) eq 'ARRAY') ? $x : [$x]

I seem to come across it in many codebases, though sometimes they use the Params::Util version:

_ARRAY($x)  ? $x : [$x]

One common use case for it is with the resulting structure from Apache configuration files:

key something

returns the value key is a scalar but

key something
key else

returns the value of key as an arrayref.

I've also seen this in type coercions that expect an array reference, but will convert a scalar into a simple array reference.

Yes, a lot of this is to work around the sloppy output from other libraries, and it relies on the assumption that the developer knows what the non-arrayref type is. But I have seen it often.

robrwo commented 3 years ago

Any movement on these? I'd work on a patch for the pure-perl part. Not that great with XS code for the XS part though.