Elastic-Model
view release on metacpan or search on metacpan
lib/Elastic/Manual/Scoping.pod view on Meta::CPAN
package Elastic::Manual::Scoping;
# ABSTRACT: An optional in-memory cache, essential for keeping weak refs live
__END__
=pod
=encoding UTF-8
=head1 NAME
Elastic::Manual::Scoping - An optional in-memory cache, essential for keeping weak refs live
=head1 VERSION
version 0.52
=head1 Warning
Scoping is an advanced topic - don't worry about L<Elastic::Model::Scope> until
you need it.
=head1 USES FOR Elastic::Model::Scope
L<Elastic::Model::Scope> acts as an in-memory cache, and serves three
futher purposes:
=head2 Keep weak-ref Elastic::Doc attributes alive
If you have a C<$post> object which has a C<user> attribute, and a C<$user>
object with a C<posts> attribute, then you will want to make (eg) the
C<< $posts->user >> attribute a
L<weak ref|https://metacpan.org/module/Moose::Manual::Attributes#Weak-references>
to avoid circular references.
But then you would have a problem:
sub add_post_to_user {
my ( $domain, $user_id, $content )= @_;
my $user = $domain->get( user => $user_id );
my $post = $domain->create(
post => {
content => $content,
user => $user;
}
);
$user->add_post($post);
$user->save;
return $post;
}
my $post = add_post_to_user($domain, 1234, 'my post content');
print $post->user->name;
# ERROR - user has disappeared!
B<Scopes keep all your doc class objects in scope, so that they don't disappear
out from under you>.
So this would work:
my $post;
{
my $scope = $model->new_scope;
$post = add_post_to_user($domain, 1234, 'my post content');
print $post->user->name;
# Clint
}
# $scope has now disappeared
print $post->user->name;
# ERROR - user has disappeared!
=head2 Reuse Elastic::Doc objects as singletons.
By default, each object is a singleton. For instance, if you do:
my $foo = $domain->get( user => 123 );
my $bar = $domain->get( user => 123 );
print $bar->name;
# Clint
$foo->name('John');
print $bar->name;
( run in 0.829 second using v1.01-cache-2.11-cpan-39bf76dae61 )