sketchucation logo sketchucation
    • Login
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info

    [Info] Allowable Classes for "set_attribute"

    Scheduled Pinned Locked Moved Developers' Forum
    57 Posts 12 Posters 5.7k Views 12 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.
    • eneroth3E Offline
      eneroth3
      last edited by

      All points and vectors change, even if you add Geom::Point3d.new to the attribute, not just those that refers to a moved vertex.

      I suppose a change in the behavior would affect more plugins than just mine. Also it would break backward compability unless you write separate code for older versions which will be much harder to maintain. Also the bounding box is always aligned with the coordinate axes so rotating entity would break the relation between the bounding box origin and a point relative to the entity.

      My website: http://julia-christina-eneroth.se/

      1 Reply Last reply Reply Quote 0
      • E Offline
        emotionally wounded beast
        last edited by

        I'm very new at this, so pardon if I'm terribly mistaken, but....

        Small, additional quirks worth mentioning:

        Directly storing / recovering Point3ds and Vector3ds in hashes will fail via Dan's method, as the inspection string will not have proper constructors for them. This is Ruby-specific, not Sketchup. That, and I'm assuming the recently noted entity-attributes-auto-transformation will not apply, as Sketchup will only see a string stored as the attribute.

        The hash creation failure:

        point = Geom;;Point3d.new(0,0,0)
        hash = {;origin => point}
        hash_str = hash.inspect
        new_hash = eval(hash_str) # Will fail
        

        hash.inspect will return => {:origin=>Point3d(0, 0, 0)}

        If you eval that it will throw the error: #<NoMethodError: undefined method `Point3d' for main:Object>

        Simple, quick solution? Store Point3ds and Vector3ds as arrays, of course.

        hash = {;origin => point.to_a}
        

        Or, alternatively, if you were dead set on keeping them as Geoms...

        hash_str = hash.inspect
        hash_str.gsub!("Point3d", "Geom;;Point3d.new")
        # Same for vectors if needed
        

        This will successfully eval to a new hash containing a Point3d (though, as previously mentioned, the point will not auto-transform with the entity it is attached to... I assume).

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

          Good point(s) (pun intended!)

          hash_str.gsub!("Point3d", "Geom::Point3d.new")
          is effectively fixing flawed inspect methods for API classes. (The hash's method calls inspect upon it's members.)

          inspect strings should be evaluable!

          .. but someone got lazy, and decided to use inspect for specially formatted output.

          I'm not here much anymore.

          1 Reply Last reply Reply Quote 0
          • eneroth3E Offline
            eneroth3
            last edited by

            I just discovered empty arrays cannot be saved as attributes between sessions in SU 6-2015 (tested on windows 7). However it works just as expected within sessions o.0. Bug report has been submitted.

            My website: http://julia-christina-eneroth.se/

            1 Reply Last reply Reply Quote 0
            • TIGT Offline
              TIG Moderator
              last edited by

              @eneroth3 said:

              I just discovered empty arrays cannot be saved as attributes between sessions in SU 6-2015 (tested on windows 7). However it works just as expected within sessions o.0. Bug report has been submitted.
              But of course your code can simply sidestep that with:
              ...get_attribute(dict, key, **[]**)
              which will either return any array which the key has as its value, OR with your own [] as its default, e.g. when it is not setup OR empty, and you get nil otherwise...

              TIG

              1 Reply Last reply Reply Quote 0
              • eneroth3E Offline
                eneroth3
                last edited by

                @tig said:

                @eneroth3 said:

                I just discovered empty arrays cannot be saved as attributes between sessions in SU 6-2015 (tested on windows 7). However it works just as expected within sessions o.0. Bug report has been submitted.
                But of course your code can simply sidestep that with:
                ...get_attribute(dict, key, **[]**)
                which will either return any array which the key has as its value, OR with your own [] as its default, e.g. when it is not setup OR empty, and you get nil otherwise...

                Yea, it's really easy to work around it once you know about it.

                My website: http://julia-christina-eneroth.se/

                1 Reply Last reply Reply Quote 0
                • S Offline
                  slbaumgartner
                  last edited by

                  @eneroth3 said:

                  @tig said:

                  @eneroth3 said:

                  I just discovered empty arrays cannot be saved as attributes between sessions in SU 6-2015 (tested on windows 7). However it works just as expected within sessions o.0. Bug report has been submitted.
                  But of course your code can simply sidestep that with:
                  ...get_attribute(dict, key, **[]**)
                  which will either return any array which the key has as its value, OR with your own [] as its default, e.g. when it is not setup OR empty, and you get nil otherwise...

                  Yea, it's really easy to work around it once you know about it.

                  I had run into the empty array problem earlier and I agree 100% with eneroth3. It is not hard to allow for this once you know about it, but there is no documentation anywhere that tells you that you need to. I wonder how many others have independently discovered this...

                  1 Reply Last reply Reply Quote 0
                  • TIGT Offline
                    TIG Moderator
                    last edited by

                    BUT the whole idea is that it always returns 'nil' if it's not set.
                    Doesn't [] === nil
                    so then that's as expected ?
                    When you 'get_' an attribute you should always default it to be the base level result: nil, 0, 0.0, "", [], false and so on...
                    Then test for the 'class' of what's returned...
                    If you don't, then how do you know what's been returned ?

                    TIG

                    1 Reply Last reply Reply Quote 0
                    • S Offline
                      slbaumgartner
                      last edited by

                      @tig said:

                      BUT the whole idea is that it always returns 'nil' if it's not set.
                      Doesn't [] === nil
                      so then that's as expected ?
                      When you 'get_' an attribute you should always default it to be the base level result: nil, 0, 0.0, "", [], false and so on...
                      Then test for the 'class' of what's returned...
                      If you don't, then how do you know what's been returned ?

                      I believe in defensive programming, so don't get me wrong: you should always verify and/or default the return from get_.

                      nil is what is returned by get_ if you never assigned a value to a particular key and provided no default, but it should not be returned when SketchUp couldn't handle the value you happened to set! Transmuting [] into nil is wrong for multiple reasons. No, []===nil is false. Performing a test such as #empty? in case the Array wasn't populated will throw an Exception because nil is not an instance of the Array class.

                      Instead of converting [] into nil (or converting any other unsupported class instance to nil) the dictionary should raise an exception when you try to set the illegal value.

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

                        Storage:
                        dict["keyname"]= ary.inspect

                        Retrieval:
                        ary = eval(dict["keyname"])

                        It has no problem with an empty array.

                        There is something in the code of the set_attribute method, that will ignore even a string representation such as "[]" ?

                        I'm not here much anymore.

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

                        Advertisement