paul@483 | 1 | Dynamic Attribute Access
|
paul@483 | 2 | ========================
|
paul@483 | 3 |
|
paul@483 | 4 | Access to attributes using specific names can either be analysed at
|
paul@483 | 5 | compile-time or supported at run-time using the object table. However, access
|
paul@483 | 6 | to arbitrary attributes which are not explicitly identified in the program as
|
paul@483 | 7 | attribute access operations requires additional support. Thus, functions such
|
paul@483 | 8 | as getattr require a means of converting string values to attribute
|
paul@483 | 9 | references.
|
paul@483 | 10 |
|
paul@483 | 11 | Although a dictionary could be used to support dynamic attribute accesses, an
|
paul@483 | 12 | alternative approach involves identifying constant strings which might refer
|
paul@483 | 13 | to active attributes. If getattr is used in a program, such string instances
|
paul@483 | 14 | are extended with an extra attribute containing the object table index which
|
paul@483 | 15 | would yield an attribute in an object table lookup. For example:
|
paul@483 | 16 |
|
paul@483 | 17 | class C:
|
paul@483 | 18 | x = 123
|
paul@483 | 19 |
|
paul@483 | 20 | attrname = "x" # generates constant with attribute giving index of "x"
|
paul@483 | 21 | # belonging to a special _accessor class
|
paul@483 | 22 |
|
paul@483 | 23 | The _accessor class is a subclass of str:
|
paul@483 | 24 |
|
paul@483 | 25 | class _accessor(str):
|
paul@483 | 26 | pass
|
paul@483 | 27 |
|
paul@483 | 28 | In pseudocode, the constant would be initialised as follows:
|
paul@483 | 29 |
|
paul@483 | 30 | "x" = _accessor(<data for "x">, <index of "x">)
|
paul@483 | 31 |
|
paul@483 | 32 | When used with getattr, an attempt is made to access the special attribute on
|
paul@483 | 33 | the given attribute name string. Such instances are able to provide an index
|
paul@483 | 34 | and this is used in the object table lookup:
|
paul@483 | 35 |
|
paul@483 | 36 | # in the native getattr(obj, attrname) function...
|
paul@483 | 37 | index = attrname._index # this yields the index offset directly
|
paul@483 | 38 |
|
paul@483 | 39 | Where getattr is not in use, no string constants are _accessor instances.
|
paul@483 | 40 |
|
paul@483 | 41 | A significant limitation of this approach is that strings cannot be combined
|
paul@483 | 42 | or modified to create strings which are then used with getattr, nor can
|
paul@483 | 43 | strings be introduced at run-time to access attributes dynamically. However,
|
paul@483 | 44 | since such string manipulation is potentially a source of errors and resists
|
paul@483 | 45 | analysis of program code, a compromise offering basic support for dynamic
|
paul@483 | 46 | access and program inspection is arguably a suitable alternative.
|