Damian Conway <[EMAIL PROTECTED]> writes:
> Piers Cawley wrote:
>
>> Bugger. I was hoping that Perl 6 was going to make a Pixie like Object
>> database easier to write; looks like I'm wrong. One of the things
>> Pixie does is to attach its control data by magic to the object itself
>> (rather than any particular variable pointing to it). This lets us do
>> all sorts of useful stuff without invading the object since we know
>> that it will carry our metadata around it. Please, consider making
>> <but> properties attach to the target of a pointer rather than to the
>> pointer itself.
>
> Err....no. That's rather the whole point of C<but> properties [*].
>
> However, if your class returns a reference to an object and that reference
> has the appropriate value properties ascribed to it (i.e. stuck on the
> *reference*), then any access through that reference (or through any
> subsequent copy of it) will see those properties.
>
> So your magic Pixie would look something like"
>
> class Pixie {
>
> method new($class: %args) {
> return $class.SUPER::new(%args)
> but Magic('whatever');
> }
>
> # etc.
> }
>
> [*] People, we just *have* to find better names for these things!
> I'd suggest we henceforth call them "value" properties (for C<but>)
> and "referent" properties (for C<is>).
Hmm... Here's Pixie's interface:
my $pixie = Pixie.new.connect('dbi:foo:bar', $user, $pass);
...
my $cookie = $pixie.insert($some_arbitrary_object);
# Time passes, we forget everything but the value of $cookie
my $pixie = Pixie.new.connect('dbi:foo:bar', $user, $pass);
my $locked_object =
$pixie.get_with_locking_strategy( $cookie,
Strategy::ExclusiveLock.new );
When $locked_object is collected, Pixie unlocks it in the
database. If, while $locked_object is in scope something else tries to
fetch an object with the same cookie (from within the same thread)
then Pixie hands 'em a reference to the same object. Right now Pixie
keeps a handle on everything by attaching 'ObjectInfo' objects to
every object that comes under its control so it can keep track of
what's going on (it's a two way link, the object has a normal ref
(via magic) to the objectinfo, which has a weakref back to the object
itself, so when the object goes out of scope, the objectinfo goes out
of scope too, triggering unlocking and other such stuff).
So, if Pixie::get_with_locking_strategy looks something like:
method get_with_locking_strategy( $self: $oid,
Strategy $lock_strategy ) {
return $self.cache_get($oid);
CATCH Exception::NotInCache {
my $flattened_object =
$self.store.get_with_locking_strategy($oid, $lock_strategy);
my $obj_info = ObjectInfo.new.set_pixie($self)
.set_oid($oid)
.set_lock_strategy($lock_strategy);
my $real_obj =
Storable::retrieve($flattened_object) but PixieInfo($obj_info);
$obj_info.set_real_object($real_obj);
$self.cache_insert($obj_info);
return $real_obj;
}
}
method cache_get( $oid ) {
my $info = %.cache{$oid} // die Exception::NotInCache.new;
return $info.real_object;
}
Will every copy of the value of $real_obj have the PixieInfo property?
Am I going mad, or is order really that important? My initial idea was
to do the C<set_real_object> and C<cache_insert> and then just do
C<return $real_obj but PixieInfo($obj_info)>, but then, if I
understand you correctly, the Info object's back reference to the real
object wouldn't have a PixieInfo property, which would in turn mean
that cache_get's return value wouldn't have the property and Bad
Things would happen. It seems counterintuitive that the order of
operations in this case should be so important.
Or am I missing something?
--
Piers