our
$VERSION
=
'0.50'
;
{
my
$attrs
= Clone::clone( Specio::Constraint::Role::Interface::_attrs() );
for
my
$name
(
qw( parent _inline_generator )
) {
$attrs
->{
$name
}{init_arg} =
undef
;
$attrs
->{
$name
}{builder}
=
$name
=~ /^_/ ?
'_build'
.
$name
:
'_build_'
.
$name
;
}
$attrs
->{methods} = {
isa
=>
'ArrayRef'
,
required
=> 1,
};
sub
_attrs {
return
$attrs
;
}
}
sub
_wrap_message_generator {
my
$self
=
shift
;
my
$generator
=
shift
;
my
$type
= (
split
/::/, blessed
$self
)[-1];
my
@methods
= @{
$self
->methods };
my
$all_word_list
= _word_list(
@methods
);
my
$allow_classes
=
$self
->_allow_classes;
unless
(
defined
$generator
) {
$generator
=
sub
{
shift
;
my
$value
=
shift
;
return
"An undef will never pass an $type check (wants $all_word_list)"
unless
defined
$value
;
my
$class
= blessed
$value
;
if
( !
defined
$class
) {
if
(
ref
$value
) {
my
$dump
= partial_dump(
$value
);
return
"An unblessed reference ($dump) will never pass an $type check (wants $all_word_list)"
;
}
return
"An empty string will never pass an $type check (wants $all_word_list)"
unless
length
$value
;
if
(
ref
\
$value
eq
'GLOB'
) {
return
"A glob will never pass an $type check (wants $all_word_list)"
;
}
if
(
$value
=~ /\A
\s*
-?[0-9]+(?:\.[0-9]+)?
(?:[Ee][\-+]?[0-9]+)?
\s*
\z/xs
) {
return
"A number ($value) will never pass an $type check (wants $all_word_list)"
;
}
$class
=
$value
if
$allow_classes
;
unless
(
defined
$class
) {
my
$dump
= partial_dump(
$value
);
return
"A plain scalar ($dump) will never pass an $type check (wants $all_word_list)"
;
}
}
my
@missing
=
grep
{ !
$value
->can(
$_
) }
@methods
;
my
$noun
=
@missing
== 1 ?
'method'
:
'methods'
;
my
$list
= _word_list(
map
{
qq['$_']
}
@missing
);
return
"The $class class is missing the $list $noun"
;
};
}
return
sub
{
$generator
->(
undef
,
@_
) };
}
sub
_word_list {
my
@items
=
sort
{
$a
cmp
$b
}
@_
;
return
$items
[0]
if
@items
== 1;
return
join
' and '
,
@items
if
@items
== 2;
my
$final
=
pop
@items
;
my
$list
=
join
', '
,
@items
;
$list
.=
', and '
.
$final
;
return
$list
;
}
1;