• Login
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
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 3 Aug 2013, 13:18

    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
    • F Offline
      fredo6
      last edited by 4 Aug 2013, 20:16

      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
      • D Offline
        Dan Rathbun
        last edited by 5 Aug 2013, 19:04

        @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
        • C Offline
          Chris Fullmer
          last edited by 5 Aug 2013, 20:42

          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
          • T Offline
            tt_su
            last edited by 6 Aug 2013, 02:12

            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
            • F Offline
              fredo6
              last edited by 7 Aug 2013, 14:32

              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
              • T Offline
                tt_su
                last edited by 7 Aug 2013, 15:20

                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 7 Aug 2013, 15:58

                  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
                  • T Offline
                    tt_su
                    last edited by 7 Aug 2013, 17:15

                    .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 9 Aug 2013, 17:51

                      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
                      • T Offline
                        tt_su
                        last edited by 9 Aug 2013, 19:05

                        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
                        1 / 1
                        • First post
                          10/11
                          Last post
                        Buy SketchPlus
                        Buy SUbD
                        Buy WrapR
                        Buy eBook
                        Buy Modelur
                        Buy Vertex Tools
                        Buy SketchCuisine
                        Buy FormFonts

                        Advertisement