While at the outset it would seem that this adheres to Postel's law ("Be liberal in what you accept, and conservative in what you send.", paraphrased.), it's a bit of a path toward madness. The more alternatives you allow, the more you are agreeing to support all those alternatives forever, for some values of forever. You are also adding complexity to your code, making param unpacking more difficult, particularly in special cases, and are painting yourself into a corner where the calling alternatives may prevent you from doing something with the args that makes perfect sense in a specific case, but differs from the myriad of ways all of the other methods in your library work.

I suggest either requiring a hashref, or permitting either a hashref or key/value pairs. Don't go providing coercing of array-refs into hash-refs, or scalar refs, or code-refs (executed to produce the args)... unless you have a good reason for providing one of those, and in that case don't provide all the other ways. It's really an overzealous application of the perceived spirit of Postel's law, but isn't founded in the actual intent.

Also if you do find yourself doing this often, consider putting the args unpacking into a subroutine or method that can be called for every sub with conforming arg handling.

If you really need to provide significantly different ways to pass args, consider writing one version of the method, and then creating wrapper methods that provide the alternate calling styles:

sub my_func { my $args = ref($_[0]) eq 'HASH' ? shift : {@_}; # do the thing } sub my_func_positional { return my_func({ message => shift(), (@_ ? (newline => shift) : ()), }); }

There is a module, Params::Smart which will handle both positional and key/value args, but the time I used it I kind of wish I had just created two subs to call instead.


Dave


In reply to Re: Thoughts on "one function, flexible arguments"? by davido
in thread Thoughts on "one function, flexible arguments"? by hornpipe2

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.