I noticed that you cannot index into an InstancePath using negative indices like you can for a normal array. Also I’ve noticed that using the leaf property of the InstancePath doesn’t yield anything if the last object in the InstancePath is a Group or ComponentInstance.
I’m not sure if these are expected behaviors and these should be feature requests or if they are bugs.
The entities class just happens to include the “” method to provide basic selection of individual objects, similar to arrays, but it is not a Ruby array object. To obtain a Ruby array that contains references to the entity objects, use:
entsarr = Sketchup.active_model.entities.to_a
Note: The array elements are references to entity objects at the time of instantiation. If the model’s entities are created or deleted after “to_a”, the separate array of references is static and not kept up to date.
Expanding on what Bruce wrote, if a new Entity is added after the Array is created, no new element will be added in the Array to reference it. Conversely, if an Entity referenced by an element of the Array is erased, the element will continue to reference the now non-valid, deleted Entity. The latter will prevent the now-dead Entity from being garbage collected until the Array itself is destroyed.
I don’t think it was an intentional decision to not allow negative indicies. Would probably make sense to mimick array access better. This is one of these cases where Ruby have so many ways of doing things that it’s challenging to remember all the mutations.
The elements of an instance path can be accessed like an array.
In the tracker issue referenced below, I question that perhaps the phrase “can be accessed like an array.” might be removed, and readers directed to use #to_a instead when needing to use negative indices or slices.
But the idea of creating an array copy still holds true for any of the API collection classes that do not quite implement enumerable methods correctly.
# Where some_instance_path is a Sketchup::InstancePath object:
patharr = some_instance_path.to_a
# ... or ...
leaf = some_instance_path.to_a[-1]
leaf_parent = some_instance_path.to_a[-2]
first = some_instance_path.to_a.first
An example of walking the instance path in reverse order:
some_instance_path.to_a.reverse.each do |ent|
# do this ...
# do that ...
# a leaf, do other - it's a primitive, cpoint, cline,
# dimension, text callout, section plane, vertex, etc.
The above may also be a good candidate task for a case block.