Why DC can't access attribute?

1. Your code is not defensive.

  • Check that your selected entity is non-false (ie, not nil) and actually has the proper dictionary, before trying to get an attribute.

  • Beware of using attribute_dictionaries['dynamic_attributes'] because it can return nil if the object’s Sketchup::AttributeDictionaries collection is empty.
    So att_dics['report'] could be the same as: nil['report'], which will cause error:
    Error: #<NoMethodError: undefined method '[]' for nil:NilClass>

2. You don’t understand how the DCs work.

  • For dynamic components, the dynamic attributes and their default values are defined in the definition’s DC dictionary. This way any new instance dragged in from the Component Manager will use the default attribute values.
    Any attribute values that are changed and unique to the dynamic instance, are cloned to a dynamic dictionary attached to the instance, with the unique value in this instance dictionary.

  • For nested dynamic groups, the dynamic attributes and their default values are always defined only in the group instance’s DC dictionary.

So, when checking for DC attributes, you need to use conditional expression(s) …


  DYNDICT ||= 'dynamic_attributes'

  def get_dc_attribute(inst, key)
    dict = inst.attribute_dictionary(DYNDICT)
    # If the instance has a dynamic dictionary, AND ...
    # it has an attribute for this key, return it's value:
    return dict[key] if dict && dict.keys.include?(key)
    # If it is a group, and we got here, then return nil:
    return nil if inst.is_a?(Sketchup::Group)
    # Otherwise, check the definition's dynamic dictionary:
    dict = inst.definition.attribute_dictionary(DYNDICT)
    return dict[key] if dict && dict.keys.include?(key)
    nil
  end
3 Likes