Understanding a Script

I came across this small script at Sketchucation which I’ve been trying to understand…

mod = Sketchup.active_model
sel = mod.selection
unless sel.empty?
  layers = []
  sel.to_a.each{|e|
    layers << e.layer
  }
  layers.flatten!;layers.uniq!
  mod.layers.each{|l|
    next if layers.include?(l)
    l.visible=false
  }
end

So…

layers = []

This is declaring an array called layers ?
And has nothing to do with the SketchUp Class Layers ?

sel.to_a.each{|e|
    layers << e.layer
  }

Here, each tag ( e.layer ) in the selection is put in the layers array ?

layers.flatten!;layers.uniq!

I think i understand what is happening here but not why.

mod.layers.each{|l|
    next if layers.include?(l)
    l.visible=false
  }

Here, the code is cycling through all the tags ( l ) in the model and if ( l ) is in the array layers it skips otherwise the tag ( l ) is turned off.

That is turning off all the layers except ones used by anything I’m the current selection. Setting layers= creates an empty Array. The name referring to the Array has nothing to do with the models layers yet, it is just a name to signify what is going to be put in the Array. The flatten and uniq are to eliminate any duplicates.

This is what was confusing me somewhat.

Thanks!

It could have been better named like: used_layers.

Yes, but I cannot see how a nested array would get pushed into the “used layers” array.
So, I think that the flatten! call is frivolous.

The actual term is making a reference assignment. The name “layers” is the reference name, and it is made to point at a new literal empty array. It is similar to doing …

layers = Array.new

There are several other things that are not needed. For example calling .to_a on the Selection object is unnecessary as that class has Enumerable mixed in.


A more succinct example (wrapped in an undo operation) would be …

mod = Sketchup.active_model
sel = mod.selection
unless sel.empty?
  used_layers = sel.map(&:layer).uniq
  unused_layers = (mod.layers.to_a - used_layers) - [mod.active_layer]
  if !unused_layers.empty?
    mod.start_operation("Hide Unused Tags")
      unused_layers.each {|tag| tag.visible= false }
    mod.commit_operation
  end
end
2 Likes