Data-Domain
view release on metacpan or search on metacpan
lib/Data/Domain.pm view on Meta::CPAN
my $msg = $self->inspect($data, $context);
# return the validated data tree if there is no error message
return $context->{gather_valid_data} if !$msg;
# otherwise, die with the error message
croak $self->name . ": invalid data because " . $self->stringify_msg($msg);
}
sub stringify_msg {
my ($self, $msg) = @_;
return does($msg, 'ARRAY') ? join ", ", map {$self->stringify_msg($_)} grep {$_} @$msg
: does($msg, 'HASH') ? join ", ", map {"$_:" . $self->stringify_msg($msg->{$_})} grep {$msg->{$_}} sort keys %$msg
: $msg;
}
sub func_signature {
my ($self) = @_;
# this method is overridden in List() and Struct() for dealing with arrays and hashes
return sub {my $params = $self->validate(@_); $params};
}
sub meth_signature {
my ($self) = @_;
my $sig = $self->func_signature;
# same as func_signature, but the first param is set apart since it is the invocant of the method
return sub {my $obj = shift; return ($obj, &$sig)}; # note: &$sig is equivalent to $sig->(@_)
}
#----------------------------------------------------------------------
# METHODS FOR INTERNAL USE
#----------------------------------------------------------------------
# Note : methods without initial underscore could possibly be useful for subclasses, either through
# invocation or through subclassing. Methods with initial underscore are really internal mechanics;
# I doubt that anybody else would want to invoke or subclass them ... but nothing prevents you from
# doing so !
sub msg {
my ($self, $msg_id, @args) = @_;
my $msgs = $self->{-messages};
my $name = $self->name;
# if using a coderef, these args will be passed to it
my @msgs_call_args = ($name, $msg_id, @args);
shift @msgs_call_args if $USE_OLD_MSG_API; # because older versions did not pass the $name arg
# perl v5.22 and above warns if there are too many @args for sprintf.
# The line below prevents that warning
no if $] ge '5.022000', warnings => 'redundant';
# if there is a user-defined message, return it
if (defined $msgs) {
for (ref $msgs) {
/^CODE/ and return $msgs->(@msgs_call_args); # user function
/^$/ and return "$name: $msgs"; # user constant string
/^HASH/ and do { if (my $msg_string = $msgs->{$msg_id}) { # user hash of msgs
return sprintf "$name: $msg_string", @args;
}
else {
last; # not found in this hash - revert to $GLOBAL_MSGS below
}
};
# otherwise
croak "-messages option should be a coderef, a hashref or a sprintf string";
}
}
# there was no user-defined message, so use global messages
if (ref $GLOBAL_MSGS eq 'CODE') {
return $GLOBAL_MSGS->(@msgs_call_args);
}
else {
my $msg_entry = $GLOBAL_MSGS->{$self->subclass}{$msg_id}
|| $GLOBAL_MSGS->{Generic}{$msg_id}
or croak "no error string for message $msg_id";
return ref $msg_entry eq 'CODE' ? $msg_entry->(@msgs_call_args)
: sprintf "$name: $msg_entry", @args;
}
}
sub name {
my ($self) = @_;
return $self->{-name} || $self->subclass;
}
sub subclass { # returns the class name without initial 'Data::Domain::'
my ($self) = @_;
my $class = ref($self) || $self;
(my $subclass = $class) =~ s/^Data::Domain:://;
return $subclass;
}
sub _initial_inspect_context {
my ($self, $data, %extra) = @_;
return {root => $data,
flat => {},
path => [],
list => [],
%extra,
};
}
sub _check_has {
my ($self, $data, $context) = @_;
( run in 2.509 seconds using v1.01-cache-2.11-cpan-a49fcb8fa48 )