sketchucation logo sketchucation
    • Login
    πŸ€‘ SketchPlus 1.3 | 44 Tools for $15 until June 20th Buy Now

    Strange behavior in derived class

    Scheduled Pinned Locked Moved Developers' Forum
    11 Posts 6 Posters 417 Views 6 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • T Offline
      tjrob
      last edited by

      Here is a set of commands in the SU Ruby console:
      ` > class A; end; puts A.new.class
      A
      nil

      class B <A; end; puts B.new.class
      B
      nil
      class C <Geom::Transformation; end; puts C.new.class
      Geom::Transformation
      nil

      (Ignore the "nil"s -- they are unused return values.)`

      How is it that C.new does not return an object with class C?
      How/why does a class derived from Geom::Transform lose its identity?
      How can I fix this -- I have a special coordinate system in my plugin and need to distinguish transformations using it from transformations using the standard coordinates.

      Note that Transformations are complicated enough that I don't want to implement them myself; I would surely get something wrong. I suppose I could make my transformation class have an instance of Geom::Transformation as a class object, but that means I need to implement a large number of functions that just pass through to that object....

      1 Reply Last reply Reply Quote 0
      • fredo6F Offline
        fredo6
        last edited by

        This seems to happen for all GEOM classes (Point3d, Vector3d).

        Frankly, I don't see why, and there must be an unknown or secret Ruby mechanism behind. Probably the Geom classes are proxies to C code and do not have all the bell and whitstles of normal SU object classes.

        I am sure Dan will have an enlightning explanation.

        Fredo

        1 Reply Last reply Reply Quote 0
        • Dan RathbunD Offline
          Dan Rathbun
          last edited by

          @fredo6 said:

          I am sure Dan will have an enlightning explanation.

          I will pass.

          Let the "official" representatives of SketchUp explain their API's behavior.

          I'm not here much anymore.

          1 Reply Last reply Reply Quote 0
          • Chris FullmerC Offline
            Chris Fullmer
            last edited by

            I'm watching and discussing internally....

            from what I can gather, the behavior is just plain ol' incorrect. We are actually looking at fixing it in a future release. But I realize that will not help with backwards compatibility. At this point, we could find no way to make it work the way you want for the classes that are broken.

            Chris

            Lately you've been tan, suspicious for the winter.
            All my Plugins I've written

            1 Reply Last reply Reply Quote 0
            • tt_suT Offline
              tt_su
              last edited by

              An alternative, which I use myself, is to put all the methods etc you had intended for the sub-class into a module and perform an instance extend after you have the Geom::Point3d instance.

              You can see the module I use in TT_Lib2 for instance: https://bitbucket.org/thomthom/tt-library-2/src/2bb264f27d9bc00c1b1f9a969e481c19385042ad/TT_Lib2/point3d_ex.rb?at=Version%202.9

              When I receive a Point3D object I can use: point.extend(TT::Point3d_Ex)
              From that point on all the content of that module is available for that instance.

              1 Reply Last reply Reply Quote 0
              • fredo6F Offline
                fredo6
                last edited by

                The strange thing about subclassing Geom::Transformation (or Geom::Point3d) is that it does not even execute the initialize method of the inherited class.

                For instance

                
                class A < Geom;;Transformation ; def initialize() ; puts "Self = #{self}" ; end ; end
                nil
                a = A.new
                #<Geom;;Transformation;0xc808ae8>
                
                

                There must be a trick since I have no clue how Ruby can do that, even if the initialize method of Geom::Transformation is a singleton method.

                Fredo

                1 Reply Last reply Reply Quote 0
                • tt_suT Offline
                  tt_su
                  last edited by

                  That's because SketchUp used an old method of allocating and initializing the data for the classes defined in C. The allocation is done explicitly in .new - which was something one had to do in Ruby 1.6. I noticed this myself when I tried to initialize an instance in Ruby C Extension using rb_class_new_instance - which failed. I had to explicitly call the .new method of the SketchUp classes.

                  1 Reply Last reply Reply Quote 0
                  • A Offline
                    Aerilius
                    last edited by

                    Subclassing SketchUp's core classes is currently impossible (see my tries with [extend()](https://bitbucket.org/Aerilius/color/src/e837419cfb80a5b29fb2c152a107447737f03f53/ae_Color.rb?at)ing the returned object).

                    @unknownuser said:

                    How can I fix this -- I have a special coordinate system in my plugin and need to distinguish transformations using it from transformations using the standard coordinates.

                    Try to create maybe a wrapper class, instead of a subclass? Create a class that stores the Geom::Transformation in a variable, and create derived methods to access/modify the original transformation.

                    1 Reply Last reply Reply Quote 0
                    • tt_suT Offline
                      tt_su
                      last edited by

                      .extend should work... It has worked for Geom::Point3d classes for me. Not tried Transformation, but it'd be surprised if it's different.

                      1 Reply Last reply Reply Quote 0
                      • T Offline
                        tjrob
                        last edited by

                        Thank you all for the discussion and suggestions.

                        I had not known about .extend() -- it works well, and does precisely what I wanted to do: distinguish different types of transformations (I use .respond_to? to tell if this instance is normal or special, and then use the function only for special ones). This is sort of "inverted inheritance", which is a very Ruby-ish thing to do πŸ™‚ .

                        1 Reply Last reply Reply Quote 0
                        • tt_suT Offline
                          tt_su
                          last edited by

                          If you extend and instance with module "FooBar" then you can use instance.is_a?(FooBar)

                          1 Reply Last reply Reply Quote 0
                          • 1 / 1
                          • First post
                            Last post
                          Buy SketchPlus
                          Buy SUbD
                          Buy WrapR
                          Buy eBook
                          Buy Modelur
                          Buy Vertex Tools
                          Buy SketchCuisine
                          Buy FormFonts

                          Advertisement