A few comments on your code:
- The line
warn "Expected ARRAY reference, found " . ref($arg) . ".";
will print, for example, 'Expected ARRAY reference, found .' if its argument is not a reference (because then ref $arg is the empty string). You may find it better to do a further check about whether $arg is a reference at all, and tailor the error message accordingly.
- In the body of the for loop that starts
for my $index(0..$#$arg)
you work with the variable $_. By default, for ( LIST ) does alias $_ to the elements of LIST in turn; but, if you pass in an explicit variable name, then that'll be the name that gets aliased. Also, since you work directly with $_, rather than using it as a subscript to @$arg, it probably makes more sense to start your loop as for my $entry ( @$arg ). (Because of Perl's internal storage, it's faster to loop directly over an array than to loop over indices and perform lots of subscripting operations.)
- Instead of if ( ref($_) ne "" ), you could just test if ( ref($_) ). The empty string is false, and (I think) no other return value of ref is.
- Why do you have (1) at the end of the line
warn "Scalar expected, reference found on position $index."; (1)
?
As to your bigger question, if you want to identify the 'row' as well as the 'column' where the wrong value occurs, you could let information flow either way: You could pass &array_of_scalars the index of the row it's checking, so that it can incorporate that in the error message; or you could provide a way (by exception-throwing, probably) for &array_of_scalars to indicate to its caller the objectionable column, and adjust &array_of_array_of_scalar's error message accordingly. Also, yes, it looks (at a cursory scan) as if Sub::Contract can do what you want; but, if you are just concerned with checking for AoAs, then a simple grep is probably closer to what you want.
UPDATE: On further reading, Sub::Contract still requires you to write your own tests; and, since it says of error messages:
When a call to a contractor breaks the contract, the constraint code will return false or croak. If it returns false, Sub::Contract will emit an error looking as if the contractor croaked.
it sounds as if it won't give (on its own) the sort of specific error messages you want. Thus, you'll still need to write the tests (which you've mostly already done). If you want (as you seem to do, and should!) to use a module rather than rolling your own,
Data::Validate::Struct might help (although, again, it seems to be going a bit overboard in this case).
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: |
| & | | & |
| < | | < |
| > | | > |
| [ | | [ |
| ] | | ] |
Link using PerlMonks shortcuts! What shortcuts can I use for linking?
See Writeup Formatting Tips and other pages linked from there for more info.