Error: #<TypeError: reference to deleted ComponentInstance>

Hello everybody. :smiley:

It is possible to add a dynamic attribute “copies” to a sub-component present in a selection using this method:

  mod = Sketchup.active_model
  sel = mod.selection
    sel.grep(Sketchup::ComponentInstance).each do |s|
      s.definition.entities.grep(Sketchup::ComponentInstance).each do |e|
	    next unless e.definition.name =~ /sub-component-1/
		e.set_attribute 'dynamic_attributes', 'copies','3'
		$dc_observers.get_latest_class.redraw_with_undo(e)
      end
    end

If I want to cancel the copies, it makes sense to change the value of the attribute to 0.

e.set_attribute 'dynamic_attributes', 'copies','0'

But that does not work and an error message is displayed in the ruby console:

Error: #<TypeError: reference to deleted ComponentInstance>
<main>:4:in `definition'
<main>:4:in `block (2 levels) in <main>'
<main>:3:in `each'
<main>:3:in `block in <main>'
<main>:2:in `each'
<main>:2:in `<main>'
-e:1:in `eval'
nil

Do you know how to avoid this problem?

Cordially

David

Do bailout validity checks at appropriate places like:

next unless obj.valid?

See, Sketchup::Entity.valid? which is inherited by all it’s subclasses.

You can also filter a collection by only valid entities, like:

good = sel.grep(Sketchup::ComponentInstance).find_all {|i| i.valid? }

Thank you for your intervention which put me on the right path Dan.
My mistake was to graft the entities!

Here is the solution that works:

  mod = Sketchup.active_model
  sel = mod.selection
    sel.each do |s|
      s.definition.entities.each do |e|
	    next unless e.definition.name =~ /sub-component-1/
		e.set_attribute 'dynamic_attributes', 'copies','0'
		$dc_observers.get_latest_class.redraw_with_undo(e)
      end
    end

That is not a solution to avoid invalid entities.

Further you open your code to fail because you have no type checking (nor filtering,) or duck typing to avoid NoMethodError exceptions.

Meaning, your supposed solution is fragile.

:roll_eyes: I was hoping you’d figure it out … oh, well.

Here is the code with “duck” typing, and validity check:

  mod = Sketchup.active_model
  sel = mod.selection
  sel.each do |s|
    next unless s.respond_to?(:definition)
    s.definition.entities.each do |e|
      next unless e.valid? && e.respond_to?(:definition)
      next unless e.definition.name =~ /sub-component-1/
      e.set_attribute('dynamic_attributes', 'copies','0')
      $dc_observers.get_latest_class.redraw_with_undo(e)
    end
  end
2 Likes

Thanks for the advice Dan.

Can you give me a specific situation that would crash my code without the checks you’ve described?

I imagine that it is customary to make checks but are they really indispencables?

Thank you

Yes, … see this topic thread …

… yes it is THIS topic thread. :wink:

And I could go through this forum and the SketchUcation forum, and add in links to many of YOUR topic threads where you do not understand the errors you are getting when you run code, … BUT I have better things to do.

Indispensable, … yes. It is called defensive programming.

You can not be 100% sure of the kinds of objects that will be in API object collections, … now nor in the future.

So I encourage you to use “duck typing” and validity checks on collection objects, and do not just assume the objects are what you hope them to be. (New kinds of objects may appear in future releases of SketchUp, and having code that makes “type assumptions” can easily break, upsetting your customers.)

You should also learn how to use rescue clauses to trap and respond gracefully to errors.
http://ruby-doc.org/core-2.2.4/doc/syntax/exceptions_rdoc.html


But, … in the end it is up to YOU to implement what we have tried to teach you. I consider that you have now been “schooled” in avoiding validity, no method and type errors. I will not further respond to any more of your posts that are obviously solved by doing “defensive” checks. It is time for the “little bird to fly on his own”. :wink:


All coders need to get to the place where they can use error messages to debug their own code, and figure out where the error is (file and line number,) and what is causing it. Getting good at troubleshooting code errors makes a person a better programmer. It is part of the learning process. In my opinion, when a coder relies too much upon other people to troubleshoot their code, they do not learn as much as when they themself figured it out.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.