Improving inspect on class objects

Allison Randal allison at parrot.org
Sat Jan 10 23:04:07 UTC 2009


Patrick R. Michaud wrote:
> On Mon, Jan 05, 2009 at 01:09:07AM -0800, Allison Randal wrote:
>> Okay, (2) is taken care of with 'get_attr_*'/'set_attr_*'. (1) works  
>> fine as a clone (not modifying, just reading), but creating a clone of  
>> the attribute metadata every time you instantiate a new object is way  
>> too expensive.
>>
>> I suggest exploring what we need out of this a little further. Again the  
>> 'inspect' vtable function isn't really right for it. It might be a class  
>> method.
> 
> There's already class method for this -- 'attributes'.  In fact, that's
> what Rakudo is actually using to get its list of attributes, but at 
> present 'attributes' just forwards to inspect_str (which is what
> brought up the original post about inspect_str).

Okay, then we can just change 'attributes' to do something different. 
There is again a question of whether it should return something that can 
be modified, but I'm okay with it being modifiable until we develop a 
deep copy-on-write strategy.

> A related question to all of this is whether the hashes returned
> by get_attr_* are also shallow-clones of the attribute metadata hash
> for any given attribute.  If we return an attribute's metadata hash
> directly, then the caller can use it to modify the attribute's
> metadata (but not the overall hash of attributes).  If we want to
> prevent even this level of modification by the caller, then get_attr_*
> needs to return a shallow clone of the attribute's metadata.  In
> this case inspect_str and attributes would return a hash of these
> shallow clones.

'inspect' and 'inspect_str' should return deep clones, so absolutely no 
data structure is the same as the original.

Ultimately, 'inspect' may do more re-formatting of the data, rather than 
simply cloning it.

> Personally, I find all of this cloning-to-prevent-modification a bit
> troubling.  I'd rather simply say "modifying the hashes returned
> from 'attributes' and get_attr_* is illegal" and not have callers
> that simply want to obtain attribute metadata incur the repeated
> cloning expense to do so. 

We're using cloning for copy-on-write semantics, but are limited to 
copy-on-copy because Parrot's COW isn't advanced enough to handle data 
structures. Agreed that this should change, but it's not a 1.0 priority.

In general, encapsulation by convention just doesn't work. If developers 
have the power to break encapsulation, they will. Perl 5 has proven that.

> This is doubly-true since the Class PMC 
> doesn't (yet?) actually use any of the attribute metadata hash entries 
> for its own purposes -- at the moment the per-attribute metadata 
> hashes seem to exist solely for the benefit of the caller.
> If Parrot is going to make using those metadata hashes expensive,
> then from a HLL perspective I think I'd rather just manage my own
> attribute metadata entirely outside of the Class PMC.

Attribute metadata is private data that the Class object uses to track 
information about its attributes. The tricky part here is that you're 
essentially creating a PIR-level subclass of Class, but the PIR code 
doesn't have access to the private data of the parent Class. At the 
moment there is no 'public' vs. 'private' distinction in the PIR 
interface to the Class object, so we're having to expose some things 
publicly that should really only be private.

> Anyway, let me know which approach you want Parrot to take
> and I'll make it happen.

To summarize:

- 'inspect' and 'inspect_str' are deep clones

- the 'attributes' method returns the actual 'attrib_metadata' hash, 
modifications are not allowed, but that convention is also not currently 
enforced

- 'get_attr_*' and 'set_attr_*' are used for modifying attributes

Allison


More information about the parrot-dev mailing list