sketchucation logo sketchucation
    • Login
    🤑 SketchPlus 1.3 | 44 Tools for $15 until June 20th Buy Now

    Note to self: Array.to_a returns self

    Scheduled Pinned Locked Moved Developers' Forum
    7 Posts 5 Posters 265 Views 5 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.
    • thomthomT Offline
      thomthom
      last edited by

      Since one should not iterate the collection one modify, such as looping over entities and removing some, I've always used .to_a - which works well when you have a Sketchup::Entities object.

      But I ran into a gotcha today: when the collection of entities is an Array. entities_array.to_a => reference to the same array. I'd always assumed it'd return a copy... 😳

      I got several methods that accepts Sketchup::Entities and Array that I need to rewrite now to ensure I get a copy of the collection, regardless of type of object.

      This public gotch-ha announcement has been brought to you by Not-Enough-Sleep Inc. Stay tuned for the next episode!

      Thomas Thomassen — SketchUp Monkey & Coding addict
      List of my plugins and link to the CookieWare fund

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

        a1=[1,2,3]
        both
        a2=a1 ### makes a new reference to the same array, 'a1' a2=a1.to_a ### makes 'a1' into an array [which it is already!] and then makes a new reference to the same array, 'a1' !!
        will still refer to a1, so consequently changing a2 changes a1 too !
        BUT
        a2=a1.dup
        makes a separate copy of a1, as will
        a2=a1+[] as adding two arrays together produces a new array, even when the second one is empty;
        and now changing a2 leaves a1 alone 😄

        TIG

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

          For clarity, Thom's Thread title states that array.dup returns the same array, but TIG says that array.dup returns a new array. Which is it actually (so I don't have to take the extra 10 seconds to test it 😄 ).

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

          1 Reply Last reply Reply Quote 0
          • thomthomT Offline
            thomthom
            last edited by

            @chris fullmer said:

            For clarity, Thom's Thread title states that array.dup returns the same array, but TIG says that array.dup returns a new array. Which is it actually (so I don't have to take the extra 10 seconds to test it 😄 ).

            Wooops - that was a confused brain connection on my part. .to_a was what I really meant. I figued you guys would just read my brain to what I really meant. 😒 😳 😆

            Thomas Thomassen — SketchUp Monkey & Coding addict
            List of my plugins and link to the CookieWare fund

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

              @tig said:

              a1=[1,2,3]
              both
              a2=a1 ### makes a new reference to the same array, 'a1' a2=a1.to_a ### makes 'a1' into an array [which it is already!] and then makes a new reference to the same array, 'a1' !!
              will still refer to a1, so consequently changing a2 changes a1 too !
              BUT
              a2=a1.dup
              makes a separate copy of a1, as will
              a2=a1+[] as adding two arrays together produces a new array, even when the second one is empty;
              and now changing a2 leaves a1 alone 😄

              To clarify, since "assignment creates references"...:

              a1=[1,2,3] ### creates a new array object referenced by a1

              a2=a1 ### makes a new reference ( a2) to the same array object that a1 is pointing at.
              a2=a1.to_a ### a1.to_a returns *self*
              both references are pointing at the same array object, so consequently that object can be changed using either reference a2 or a1.
              BUT
              a2=a1.dup ### makes a new array object, (referenced by a2,) that is a copy of the array object that a1 is pointing at.

              I'm not here much anymore.

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

                The Ruby RDoc says:


                Array#to_a || Array#to_ary
                Returns *self*. If called on a subclass of Array, converts the receiver to an Array object.


                Object#clone
                Produces a shallow copy of *self* — the instance variables of *self* are copied, but not the objects they reference. Copies the frozen and tainted state of *self*. See also the discussion under Object#dup.


                Object#dup
                Produces a shallow copy of *self* — the instance variables of *self* are copied, but not the objects they reference. dup copies the tainted state of *self*. See also the discussion under Object#clone. In general, clone and dup may have different semantics in descendent classes. While clone is used to duplicate an object, including its internal state, dup typically uses the class of the descendent object to create the new instance.

                This method may have class-specific behavior. If so, that behavior will be documented under the #initialize_copy method of the class.


                Note: I changed the words "obj" to " self" fo clarity.



                The old "Pick-Axe" book Programming Ruby, says:

                What happens when you copy a frozen object? That depends on the method you use. If you call an object's clone method, the entire object state (including whether it is frozen) is copied to the new object. On the other hand, dup typically copies only the object's contents---the new copy will not inherit the frozen status.

                and also:

                <span class="syntaxdefault">person1 </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxstring">"Tim"</span><span class="syntaxdefault">  <br />person2 </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> person1  <br />person1</span><span class="syntaxkeyword">[</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">]</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxstring">'J'</span><span class="syntaxdefault">  <br />person1  » </span><span class="syntaxstring">"Jim"</span><span class="syntaxdefault">  <br />person2  » </span><span class="syntaxstring">"Jim"</span><span class="syntaxdefault"> <br /> </span>
                

                Assignment aliases objects, potentially giving you multiple variables that reference the same object. But can't this cause problems in your code? It can, but not as often as you'd think (objects in Java, for example, work exactly the same way). For instance, in the example in Figure 3.1, you could avoid aliasing by using the dup method of String, which creates a new String object with identical contents.

                <span class="syntaxdefault">person1 </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxstring">"Tim"</span><span class="syntaxdefault">  <br />person2 </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> person1</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">dup  <br />person1</span><span class="syntaxkeyword">[</span><span class="syntaxdefault">0</span><span class="syntaxkeyword">]</span><span class="syntaxdefault"> </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> </span><span class="syntaxstring">"J"</span><span class="syntaxdefault">  <br />person1  » </span><span class="syntaxstring">"Jim"</span><span class="syntaxdefault">  <br />person2  » </span><span class="syntaxstring">"Tim"</span><span class="syntaxdefault"> <br /> </span>
                

                I'm not here much anymore.

                1 Reply Last reply Reply Quote 0
                • AdamBA Offline
                  AdamB
                  last edited by

                  @dan rathbun said:

                  @tig said:

                  a1=[1,2,3]
                  both
                  a2=a1 ### makes a new reference to the same array, 'a1' a2=a1.to_a ### makes 'a1' into an array [which it is already!] and then makes a new reference to the same array, 'a1' !!
                  will still refer to a1, so consequently changing a2 changes a1 too !
                  BUT
                  a2=a1.dup
                  makes a separate copy of a1, as will
                  a2=a1+[] as adding two arrays together produces a new array, even when the second one is empty;
                  and now changing a2 leaves a1 alone 😄

                  To clarify, since "assignment creates references"...:

                  a1=[1,2,3] ### creates a new array object referenced by a1

                  a2=a1 ### makes a new reference ( a2) to the same array object that a1 is pointing at.
                  a2=a1.to_a ### a1.to_a returns *self*
                  both references are pointing at the same array object, so consequently that object can be changed using either reference a2 or a1.
                  BUT
                  a2=a1.dup ### makes a new array object, (referenced by a2,) that is a copy of the array object that a1 is pointing at.

                  Nice round-up..

                  But be aware #dup performs a shallow copy. So any proper objects (as opposed to simple numbers) in that array are copied by reference.

                  So:

                  a = [10, 20, [30,31,32]]
                  c = a.dup
                  a[2][0] = 'Tada!'
                  c
                  will print:
                  [10, 20, ["Tada!", 31, 32]]

                  Developer of LightUp Click for website

                  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