package Railway::Cleanup;
use Evo::Base -base;

sub cleanup($self) { delete $self->{$_} for $self->cleanup_list }

state $CLEANUP_ATTRS = {};

sub register_cleanup($class, $attr) {
  $class = ref $class || $class;
  $CLEANUP_ATTRS->{$class} //= [];
  push $CLEANUP_ATTRS->{$class}->@*, ref $attr eq 'ARRAY' ? (@$attr) : $attr;
}

sub attr_cleanup {
  my ($class, $attr, $default) = @_;
  $class->register_cleanup($attr);
  $class->attr($attr, $default);
}

sub cleanup_list($class) {
  my @list;
  my @classes = (ref($class) || $class, _parents($_[0]));
  $CLEANUP_ATTRS->{$_} && push @list, $CLEANUP_ATTRS->{$_}->@* for @classes;
  @list;
}

sub _parents {
  my $class = ref $_[0] || $_[0];
  my @classes;

  ## no critic
  no strict 'refs';
  while (my @parents = @{$class . "::ISA"}) {
    if (@parents > 1) {
      my $err = "multiple inheritance isn't supported yet: %s <- [%s] ";
      die sprintf($err, $class, join('; ', @parents)) if @parents > 1;
    }
    push @classes, $class = $parents[0];
  }
  @classes;
}

1;

# ABSTRACT: autocleaner

__END__

=pod

=encoding UTF-8

=head1 NAME

Railway::Cleanup - autocleaner

=head1 VERSION

version 0.009

=head1 METHODS

=head2 cleanup

cleanup attributes

=head2 register_cleanup

register a keys for cleanup

=head2 cleanup_list

returns a list of attributes that will be cleared with L</"cleanup">

=head2 attr_cleanup

Invoke L<Evo::Base/"attr"> and register it for cleanup

=head1 AUTHOR

alexbyk.com

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2015 by alexbyk.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut
