Extending SketchUp entities
-
Just for kicks...
On PC, SU 8.0M1, Ruby v1.8.7-p299 :
face.extend(Dan)
%(#400000)[Error: #<TypeError: (eval):0:in
extend': wrong argument type Class (expected Module)>]` -
I meant module. I just types up a fake example.
Regardless,
.extend
on an entity will affect all scripts trying to access it. -
What about keeping your own collection of your own special faces. I guess this is what you're trying to avoid?
` sel = Sketchup.active_model.selection
face = sel[0]
MyPrettyFaces.add( face )MyPrettyFaces.is_pretty?( face )
true`
-
Now if you wish to automate this, similar to a mixin, you need to write your own "Extender" submodule within your namespace:
module TT;;Extender def self.add_method_has_dictionary?(obj) unless obj.is_a?(Sketchup;;Entity) raise(TypeError,"wrong argument type #{obj.class.name} (expected Sketchup;;Entity subclass)",caller) end Object.instance_eval %q[ def obj.has_dictionary?(dict_name=nil) return false unless ( dicts = self.attribute_dictionaries() ) dict_name = '' if dict_name.nil? unless dict_name.is_a?(String) raise(TypeError,"wrong argument type #{dict_name.class.name} (expected String)",caller) end dicts.any?{|dict| dict.name == dict_name } end # def ] end # def add_method_has_dictionary?(obj) end # module TT;;Extender
Then to use:
face = sel[0] %(#400000)[>> #<Sketchup::Face:0x62c6090>] TT::Extender.add_method_has_dictionary?(face) %(#400000)[>> nil] face.respond_to?(:has_dictionary?) %(#400000)[>> true]
-
Adding a singleton method to a SINGLE instance object is quite easy:
face.is_a?(Sketchup::Face)
true
def face.has_dictionary?(dict_name=nil) return false unless ( dicts = self.attribute_dictionaries() ) dict_name = '' if dict_name.nil? raise(TypeError,"wrong argument type #{dict_name.class.name} (expected String)",caller) unless dict_name.is_a?(String) dicts.any?{|dict| dict.name == dict_name } end
-
@dan rathbun said:
` face.respond_to?(:has_dictionary?)
true`
And if another script was to iterate over the face, would it then get a non-extended version of the face entity?
-
@thomthom said:
@dan rathbun said:
` face.respond_to?(:has_dictionary?)
true`
And if another script was to iterate over the face, would it then get a non-extended version of the face entity?
No it would get THE instance object, with all it's inherited instance methods, AND any singleton methods (including the newly attached
:has_dictionary?
method.)UNLESS after using the method, you decided to unattach it somehow... IF Ruby allows doing that.
I don't think it does.. becauseundef_method()
andremove_method()
are private class methods, and are not inherited by the instances.But what's the big deal? It's better than modifying the base API class, isn't it?
Your other option is to create yourself a mixin module, that you mixin to YOUR OWN modules, that creates private methods, such as:
ent_has_dictionary?(entity,dict_name)
-
However .. I'm beginning to form a concept in my mind.. how perhaps scripters could create custom instance methods for any API class, without actually modifying the class... more thought and experimentation will be required.
-
@dan rathbun said:
But what's the big deal? It's better than modifying the base API class, isn't it?
If my script iterate the entities in a model and extends them with my mixin module - then I wouldn't want to affect other scripts. It'd be the same as modifying the base class.
-
@thomthom said:
@dan rathbun said:
But what's the big deal? It's better than modifying the base API class, isn't it?
If my script iterate the entities in a model and extends them with my mixin module - then I wouldn't want to affect other scripts. It'd be the same as modifying the base class.
We'll yes.. if you end up defining a new singleton method for EVERY
Sketchup::Entity
subclass instance in the model(s), then it would be comparable to extending all the classes themselves.Also.. a singleton method, is in effect, a single instance override of any inherited method of the same name, so (referring to my previous example,) if Google later ended up adding a
:has_dictionary?
method to the APISketchup::Entity
superclass, my example would be overriding that method, on an individual instance basis.
Advertisement