my $source = Sub::ParamObject->new({ selector => sub { my $self = shift; return unless $_[0] =~ /^(filename|url)$/; return if @$self{qw(filename url)} and !exists $self->{$1}; }, filename => sub { my $self = shift; return (!exists $self->{selector} or $self->{selector} eq 'filename') and $_[1] =~ qr/^\w+$/; }, url => sub { my $self = shift; return (!exists $self->{selector} or $self->{selector} eq 'url') and $_[1] =~ qr!^https?://!i }, }); #### my $source = Sub::ParamObject->new({ selector => [ qr/^(filename|url)$/, sub { @{$_[0]}{qw(filename url)} and !exists $self->{$_[1]} }, ], filename => [ qr/^\w+$/, sub { !exists $_[0]->{filename} or $_[0]->{selector} eq 'url' }, ], url => [ qr!^https?://!i, sub { !exists $_[0]->{filename} or $_[0]->{selector} eq 'url' }, ], }); #### my $source = Sub::ParamObject->new(test => { selector => { value => qr/^(filename|url)$/, }, filename => { value => qr/^\w+$/, }, url => { value => qr!^https?://!i, }, }, if_valid => { selector => sub { $_[0]->add_check($_[1] eq 'url' ? 'filename' : 'url', forbidden => sub { return }); }, filename => sub { $_[0]->add_check(selector => need_filename => sub { $_[1] ne 'url' }); }, url => sub { $_[0]->add_check(selector => need_url => sub { $_[1] ne 'filename' }); }, });