By reference or by value? Or Fixnum assignment is different?

Hi,

I am new to Ruby, just start reading the pickaxe.

Here I have a question regarding passing parameters by value or
reference. Hence everything is an object and the book mentioned for
a=“abc”; b=a just created a new reference to “abc”, I guess it applies
to everything is an object (could I be wrong here?).

Seems it is not the case for Fixnum.

#sample code from pickaxe

def n_times(thing)

lambda {|n| thing * n}

end

=> nil

#Fixnum and String

a=b=23

=> 23

c=d=“abc”

=> “abc”

#c, d and ‘thing’ are reference to same thing, just as the book said

p2=n_times©

=> #<Proc:0x802b7980@(irb):18 (lambda)>

p2.call(3)

=> “abcabcabc”

c.insert(-1,‘d’); d.insert(-1, ‘e’)

=> “abcde”

p2.call(3)

=> “abcdeabcdeabcde”

#not apply to Fixnum???

p1=n_times(a)

=> #<Proc:0x802c0bc0@(irb):18 (lambda)>

p1.call(3)

=> 69

a=a+1; b=b+1

=> 24

p1.call(3)

=> 69

At first, seems to me when pass Fixnum, Ruby makes a copy. But further
dig seems it was the assignment:

a=b=10

=> 10

p a.object_id; p b.object_id

21

21

=> 21

a+=1

=> 11

p a; p b

11

10

=> 10

object_id changed after assignment!

p a.object_id; p b.object_id

23

21

=> 21

Why Fixnum behaves different from String? Is the number class (e.g.
Fixnum, Float) the only one in Ruby core that behave like this? A little
bit confusing here

a=b=10

=> 10

p a.object_id; p b.object_id

21

21

=> 21

a=a<<1

=> 20

a was changed!

p a.object_id; p b.object_id

41

21

=> 21

c=d=“abc”

=> “abc”

p c.object_id; p d.object_id

-1072646678

-1072646678

=> -1072646678

c=c << “d”

=> “abcd”

same operator << (ok, different operation for Fixnum)

didn’t change the obj id for String

p c.object_id; p d.object_id

-1072646678

-1072646678

=> -1072646678

p d

“abcd”

Thanks for reading. I appreciate any help/comment.

J.T

Fixnum is immutable. What happens when you add 1 to your Fixnum is that
it becomes a different Fixnum with a different object id.

String is mutable. When you modify a String, it retains its object id,
but each instance of a String has a different object id.

irb(main):006:0> a.object_id
=> 3
irb(main):007:0> b.object_id
=> 3
irb(main):008:0> a = “a”
=> “a”
irb(main):009:0> b = “a”
=> “a”
irb(main):010:0> a.object_id
=> 24142944
irb(main):011:0> b.object_id
=> 23626116

If it helps: a += 1 is not rubys increment, it is shorthand for a = a +

  1. So you are reassigning a.

On Thu, Dec 19, 2013 at 11:29 PM, Jason T. [email protected]
wrote:

Now I am clear for Fixnum, operators create new object instead of operate on
the current one (immutable J), and assignment changed the reference. At
least as of now I havent found a method to change the Fixnum object
directly. For String, there are methods/operators operate on the current
object (mutable).

From a language user’s point of view all variables are references.
Technically (i.e. under the hood) there are some optimizations done -
but they do not affect usage. I’d say it’s best to ignore the under
the hood part for now while you are learning the language. It may
cause unnecessary confusion. You can still look at this later.

To add a fun fact: you can actually attach state to a Fixnum:

irb(main):017:0> x=1
=> 1
irb(main):018:0> x.instance_variable_set ‘@foo’, “bar”
=> “bar”
irb(main):019:0> x.instance_variable_get ‘@foo
=> “bar”
irb(main):020:0> 1.instance_variable_get ‘@foo
=> “bar”
irb(main):021:0> 1.freeze
=> 1
irb(main):022:0> x.instance_variable_set ‘@foo’, “buz”
RuntimeError: can’t modify frozen object
from (irb):22:in instance_variable_set' from (irb):22 from /usr/bin/irb:12:in

That does not mean that you should do it or that it’s a good idea. For
all practical purposes you should view all numeric types as immutable.
A bit more on numbers and operators in Ruby:

http://blog.rubybestpractices.com/posts/rklemme/019-Complete_Numeric_Class.html

Kind regards

robert

Thanks Joel, Florian for the explaination.

Now I am clear for Fixnum, operators create new object instead of
operate on the current one (immutable J), and assignment changed the
reference. At least as of now I haven’t found a method to change the
Fixnum object directly. For String, there are methods/operators operate
on the current object (mutable).

Thanks again.

J.T

From: ruby-talk [mailto:[email protected]] On Behalf Of
Jason T.
Sent: Thursday, December 19, 2013 11:42 AM
To: [email protected]
Subject: by reference or by value? Or Fixnum assignment is different?

Hi,

I am new to Ruby, just start reading the pickaxe.

Here I have a question regarding passing parameters by value or
reference. Hence everything is an object and the book mentioned for
a=“abc”; b=a just created a new reference to “abc”, I guess it applies
to everything is an object (could I be wrong here?).

Seems it is not the case for Fixnum.

#sample code from pickaxe

def n_times(thing)

lambda {|n| thing * n}

end

=> nil

#Fixnum and String

a=b=23

=> 23

c=d=“abc”

=> “abc”

#c, d and ‘thing’ are reference to same thing, just as the book said

p2=n_times(c)

=> #<Proc:0x802b7980@(irb):18 (lambda)>

p2.call(3)

=> “abcabcabc”

c.insert(-1,‘d’); d.insert(-1, ‘e’)

=> “abcde”

p2.call(3)

=> “abcdeabcdeabcde”

#not apply to Fixnum???

p1=n_times(a)

=> #<Proc:0x802c0bc0@(irb):18 (lambda)>

p1.call(3)

=> 69

a=a+1; b=b+1

=> 24

p1.call(3)

=> 69

At first, seems to me when pass Fixnum, Ruby makes a copy. But further
dig seems it was the assignment:

a=b=10

=> 10

p a.object_id; p b.object_id

21

21

=> 21

a+=1

=> 11

p a; p b

11

10

=> 10

object_id changed after assignment!

p a.object_id; p b.object_id

23

21

=> 21

Why Fixnum behaves different from String? Is the number class (e.g.
Fixnum, Float) the only one in Ruby core that behave like this? A little
bit confusing here

a=b=10

=> 10

p a.object_id; p b.object_id

21

21

=> 21

a=a<<1

=> 20

a was changed!

p a.object_id; p b.object_id

41

21

=> 21

c=d=“abc”

=> “abc”

p c.object_id; p d.object_id

-1072646678

-1072646678

=> -1072646678

c=c << “d”

=> “abcd”

same operator << (ok, different operation for Fixnum)

didn’t change the obj id for String

p c.object_id; p d.object_id

-1072646678

-1072646678

=> -1072646678

p d

“abcd”

Thanks for reading. I appreciate any help/comment.

J.T