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

    By value or by reference?

    Scheduled Pinned Locked Moved Developers' Forum
    20 Posts 5 Posters 2.2k 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

      Why do these two things differ: I pass a string to a method and modify the string:

      def m3(a); a += 'bar'; end

      ` > x = 'foo'
      foo

      m3(x)
      foobar
      x
      foo`

      ...and the string outside the method is not changed.

      But use a Point3d:

      def m4(p); p.x = 99; end

      ` > n = Geom::Point3d.new(1,2,3)
      Point3d(1, 2, 3)

      m4(n)
      99
      n
      Point3d(99, 2, 3)`

      And now it does change...

      When I pass Point3d objects to methods that modify the passed argument, I use p2 = p1.clone - but is this the best way to do get a local copy to work on?

      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

        @thomthom said:

        Why do these two things differ: I pass a string to a method and modify the string:
        def m3(a); a += 'bar'; end
        (from the Ruby 'Pick-Axe' book):
        str + aString -> aNewString
        + Concatenation---Returns a new String containing aString concatenated to str.

        @thomthom said:

        ` > x = 'foo'
        foo

        m3(x)
        foobar
        x
        foo`
        ...and the string outside the method is not changed.

        Because 'foobar' is the new string object that was transparently constructed with String.new by Ruby.

        I'm not here much anymore.

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

          Ok, but what about this one?

          ` > x = 'foo'
          foo

          def m3(a); a = 'bar'; end
          nil
          m3(x)
          bar
          x
          foo`

          ❓

          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

            @thomthom said:

            a += 'bar'

            Just a quick note about += for String objects.

            (We also discussed this in another thread.) %(#4040BF)[EDIT ( 😕 got confused for a min; removed previous statement.)]
            My advice is, for less confusion, use the proper String append operator: (It's the same work for typing!)
            a << 'bar'

            ADD: IMHO, the interpreter should raise a SyntaxError when it sees += for Strings. I wonder if a Warning is output?
            UPDATE: No, I tested += with $VERBOSE set to true, and no warning is output.

            I'm not here much anymore.

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

              @thomthom said:

              Ok, but what about this one?
              ` > x = 'foo'
              foo

              def m3(a); a = 'bar'; end
              nil
              m3(x)
              bar
              x
              foo`

              ..the above, is the same as:
              @thomthom said:

              ` def m3(a); a += 'bar'; end

              x = 'foo'
              foo
              m3(x)
              foobar
              x
              foo`
              .. with respect to that:

              (1) the reference a, is at method start, pointing at the same string object 'foo' that the reference x is pointing at; ..and

              (2) then the expression on the right of the '=', in both cases, results in the creation of a new string object by Ruby.
              ..(a) In case 1, Ruby calls String.new('bar') (we'll call it: newbarstr.)
              ..(b) In case 2, Ruby first expands a += 'bar', into a = a + 'bar', then (as in case 1,) evaluates the right-hand expression, transparently passing literal string args to String.new, keeping track of the anonymous pointers to the new string objects. In this example there is only one (we'll call it newbarstr.) Then, it calls a.+(newbarstr) which is the string concatenation method, that returns yet another new string object created by Ruby (we'll call it foobarstr, but remember Ruby uses temporary numerical identifiers.) So at this point the right-hand expression is now done and set to temp string object foobarstr.

              (3) NOW.. both cases make a REFERENCE assignment, which assigns the reference a to point at the new String objects created from their evaluations.

              (4) Lacking any specific return expression, the method returns the last result, which is the value of the object that a was made to point at, which is NOT the object 'foo'.

              (5) Since the method call was made "stand-alone" and it's result not referenced, when the method exits, a will disposed of by Garbage Collection, along with any temporary objects Ruby used within the method.

              (6) .. all that's left, is reference x pointing at poor 'lil string object 'foo'.

              += vs. <<
              Looking back at (2)(b) above, and realizing all the work that is going on, and string objects being created, just to glue two substrings together.. we should all want to use << (the String append method,) instead.
              The main reason is, that it only creates one temporary string, IF the argument is a literal; otherwise NO temporary string, IF the argument is a reference to an existing string object.
              String.<< instead directly modifies the receiver string object by appending the string argument object onto it.

              Bottom line: Free Your Ruby Mind !! 💭
              Throw away the word 'variable' and think 'reference'.
              $reference, global_reference, local_reference, instance_reference, @reference, class_reference, @@reference, module_reference ... reference, Reference, REFERENCE !

              I'm not here much anymore.

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

                @thomthom said:

                Why do[es] ... Point3d [differ?]

                def m4(p); p.x = 99; end

                ` > n = Geom::Point3d.new(1,2,3)
                Point3d(1, 2, 3)

                m4(n)
                99
                n
                Point3d(99, 2, 3)`
                And now it does change...

                Apples and Oranges.

                In this case, your calling a 'method operator' ie: Geom::Point3d.x= that happens to have a '=' character in the method name. It's not the same as the Ruby hard-coded = operator.

                Your getting confused because the interpreter allows you to insert a space into the method call.

                Also.. Geom::Point3d.x= is more similar to String.<<, in that the method doesn't replace an entire object, it only modifies part of the object.
                Specifically, Geom::Point3d.x= is an attribute setter method, involving Numerics, so no temporary Integer, and p is still pointing at the same object n is, so naturally, yes the common object gets modified.

                Since Geom::Point3d has no dup method, you'll have to use clone to create a copy.

                I'm not here much anymore.

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

                  @dan rathbun said:

                  In this case, your calling a 'method operator' ie: Geom::Point3d.x= that happens to have a '=' character in the method name. It's not the same as the Ruby hard-coded = operator.

                  Your getting confused because the interpreter allows you to insert a space into the method call.

                  Ahah! This is the core of my confusion indeed!

                  .x= (which can be written .x =) is really just a Ruby naming conversion for .set_x.

                  Thanks for this explanation Dan. Appreciate it.

                  So using p2 = p1.clone is the proper way to get a copy of a point then?

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

                  1 Reply Last reply Reply Quote 0
                  • tbdT Offline
                    tbd
                    last edited by

                    see also The Ruby programming language By David Flanagan, Yukihiro Matsumoto

                    SketchUp Ruby Consultant | Podium 1.x developer
                    http://plugins.ro

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

                      @unknownuser said:

                      see also The Ruby programming language By David Flanagan, Yukihiro Matsumoto

                      Interesting link. I think I need to read further into that book.
                      Did remind me of another thing about Ruby - true/ false, why they don't equal to 1 and 0. I've burned myself a couple of times on that one.

                      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

                        @thomthom said:

                        So using p2 = p1.clone is the proper way to get a copy of a point then?

                        Only way if you keep it a Point3d. If you convert to Array, then you have the real 'proper' .dupand .clonethat are inherited correctly from Object.

                        The Geom::Point3ddid inherit .dupbut it does not work, it returns nil.
                        And Google overrode the standard .clone, and the new one does not pass on taintedness and frozen state correctly.

                        I'm not here much anymore.

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

                          Well, if .to_a is faster than cloning a Point3d then I can live with that. I just need to grab a copy of some x,y,z co-ordinates and modify its values - as fast as possible.

                          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

                            @thomthom said:

                            Well, if .to_a is faster ...

                            .to_a is 1 less char to type than .clone 😆

                            .. and itwillcreate a new Array object, and since the GSUT extended the Array class with .x, .y, .z etc, it's same same...

                            I'm not here much anymore.

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

                              Only preview of the book - not the whole thing. I just placed an order for it. I don't like reading books on screen. Hurts my eyes.

                              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

                                @thomthom said:

                                @unknownuser said:

                                see also The Ruby programming language By David Flanagan, Yukihiro Matsumoto

                                Interesting link. I think I need to read further into that book.

                                No Kidding! Yukihiro Matsumoto is "Matz" the inventor of Ruby! 🤓

                                I didn't know Google Books had this. 👍

                                I'm not here much anymore.

                                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