Context-Singleton

 view release on metacpan or  search on metacpan

lib/Context/Singleton/Frame.pm  view on Meta::CPAN


use v5.10;
use strict;
use warnings;

package Context::Singleton::Frame;

our $VERSION = v1.0.5;

use List::Util;
use Scalar::Util;

use Context::Singleton::Frame::DB;
use Context::Singleton::Exception::Invalid;
use Context::Singleton::Exception::Deduced;
use Context::Singleton::Exception::Nondeducible;
use Context::Singleton::Frame::Promise;
use Context::Singleton::Frame::Promise::Builder;
use Context::Singleton::Frame::Promise::Rule;

use overload (
	'""' => sub { ref ($_[0]) . '[' . $_[0]->{depth} . ']' },
	fallback => 1,
);

sub new {
	my ($class, %proclaim) = @_;
	my $self = {
		promises    => {},
		depth       => 0,
		db          => $class->default_db_instance,
	};

	if (ref $class) {
		$self->{root}   = $class->{root};
		$self->{parent} = $class;
		$self->{db}     = $class->{db};
		$self->{depth}  = $class->{depth} + 1;

		$class = ref $class;
	}

	unless ($self->{root}) {
		$self->{root} = $self;
		Scalar::Util::weaken $self->{root};
	}

	$self = bless $self, $class;

	$self->proclaim (%proclaim);

	return $self;
}

sub depth {
	$_[0]->{depth};
}

sub parent {
	$_[0]->{parent};
}

sub default_db_class {
	'Context::Singleton::Frame::DB';
}

sub default_db_instance {
	$_[0]->default_db_class->instance;
}

sub db {
	$_[0]->{db};
}

sub debug {
	my ($self, @message) = @_;

	my $sub = (caller(1))[3];
	$sub =~ s/^.*://;

	use feature 'say';
	say "# [${\ $self->depth}] $sub ${\ join ' ', @message }";
}

sub _build_builder_promise_for {
	my ($self, $builder) = @_;

	my $promise = $self->_class_builder_promise->new (
		depth   => $self->depth,
		builder => $builder,
	);

	my %optional = $builder->default;
	my %required = map +($_ => 1), $builder->required;
	delete @required{ keys %optional };

	$promise->add_dependencies (
		map $self->_search_promise_for ($_), keys %required
	);

	$promise->set_deducible (0) unless keys %required;

	$promise->listen ($self->_search_promise_for ($_))
		for keys %optional;



( run in 0.761 second using v1.01-cache-2.11-cpan-39bf76dae61 )