# Everything's an object, right?

**URL:** <https://www.ruby-forum.com/t/everythings-an-object-right/72674>\
**Category:** Ruby\
**Created:** [February 24, 2006, 4:59am UTC](https://www.ruby-forum.com/t/everythings-an-object-right/72674 "2006-02-24T04:59:06Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nathan\_Morse](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/3be4f8/32.png) [@Nathan\_Morse](https://www.ruby-forum.com/u/Nathan_Morse)\
**Post date:** [February 24, 2006, 4:59am UTC](https://www.ruby-forum.com/t/everythings-an-object-right/72674/1 "2006-02-24T04:59:06Z")

</div>

I was talking to a coworker today about the Ruby, and we were  
discussing how in Ruby everything is an object. He wondered if  
everything was call-by-reference, and my knee jerk reaction was yes.

Then I ran the following irb session…

------------------- START IRB -------------------------

def foo(x)  
x = ‘k’ + x[1…x.size]  
x  
end

def bar(x)  
x[0] = ‘k’  
x  
end

k = ‘crazy’  
=\> “crazy”

foo(k)  
=\> “krazy”

k  
=\> “crazy” # !?!?!?!?!

bar(k)  
=\> “krazy”

k  
=\> “krazy” # As expected.

------------------- END IRB -------------------------

Can someone explain to me why the method foo() doesn’t modify k while  
bar() does? I suppose it has something to do with the fact that I’m  
using an asignment statement in foo() but modifiying the parameter  
“in-place” for bar(). Still, I’m a bit confused.

[author’s note: Yes, I know my example isn’t very “Rubyish”. I just  
want to get a better handle on the language.]

Thanks!

-Nathan

---

<div class="post-metadata">

**Author:** ![Nathan\_Morse](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/3be4f8/32.png) [@Nathan\_Morse](https://www.ruby-forum.com/u/Nathan_Morse)\
**Post date:** [February 24, 2006, 5:08am UTC](https://www.ruby-forum.com/t/everythings-an-object-right/72674/2 "2006-02-24T05:08:11Z")

</div>

On Fri, Feb 24, 2006 at 12:58:38PM +0900, Nathan Morse wrote:

> def foo(x)  
> x = ‘k’ + x[1…x.size]  
> x  
> end
> 
> def bar(x)  
> x[0] = ‘k’  
> x  
> end

String#+ creates a new object. String#[] edits the object in place.

def foo(x)  
x = ‘k’ + x[1…x.size]  
[x, x.object\_id]  
end

def bar(x)  
x[0] = ‘k’  
[x, x.object\_id]  
end

> > k = ‘crazy’  
> > =\> “crazy”
> 
> > k.object\_id  
> > =\> 2584064
> 
> > foo k  
> > =\> [“krazy”, 2580574]
> 
> > bar k  
> > =\> [“krazy”, 2584064]
> 
> > foo k  
> > =\> [“krazy”, 2577004]
> 
> > bar k  
> > =\> [“krazy”, 2584064]

marcel

---

<div class="post-metadata">

**Author:** ![Nathan\_Morse](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/3be4f8/32.png) [@Nathan\_Morse](https://www.ruby-forum.com/u/Nathan_Morse)\
**Post date:** [February 24, 2006, 5:38am UTC](https://www.ruby-forum.com/t/everythings-an-object-right/72674/3 "2006-02-24T05:38:41Z")

</div>

What about when I don’t use String#+ ?

* * *

> def foo(x)  
> x = “krazy”  
> x  
> end  
> =\> nil

> def bar(x)  
> x[0] = ‘k’  
> x  
> end  
> =\> nil

> k = ‘crazy’  
> =\> “crazy”

> foo(k)  
> =\> “krazy”

> k  
> =\> “crazy”

> bar(k)  
> =\> “krazy”

> k  
> =\> “krazy”

---

<div class="post-metadata">

**Author:** ![Nathan\_Morse](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/3be4f8/32.png) [@Nathan\_Morse](https://www.ruby-forum.com/u/Nathan_Morse)\
**Post date:** [February 24, 2006, 6:09am UTC](https://www.ruby-forum.com/t/everythings-an-object-right/72674/4 "2006-02-24T06:09:39Z")

</div>

Nathan Morse wrote:

> What about when I don’t use String#+ ?

Look at it this way. You’re not “passing by reference.” You’re  
passing references by value. 🙂

Learn to distinguish between variables and objects. The former  
are merely “labels” if you will.

```
a = b = c = "hello" # three variables, one object

```

Then remember that assignment always “wipes out” the old reference.  
Assignment doesn’t change the old object at all.

```
a = b = "hi" # a and b both refer to "hi"
a = "bye" # but now a refers to "bye"

```

So assigning a variable is different from changing an object.  
Look at this:

```
a = b = "hi"
b[0] = "f"
p a # "fi"

```

We’re changing the _object_ referred to by b (which is the same  
one referred to by a). We’re not making b refer to a different  
object.

Or check this out. Both result in the value “foobar” – but there  
is a difference.

```
a = "foo"
b = "foo"
p a.object_id # -542440758
p b.object_id # -542444578

a << "bar"
b += "bar"
p a.object_id # -542440758
p b.object_id # -542466128 (a new object!)

```

Does this help any?

Hal

---

<div class="post-metadata">

**Author:** ![Nathan\_Morse](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/3be4f8/32.png) [@Nathan\_Morse](https://www.ruby-forum.com/u/Nathan_Morse)\
**Post date:** [February 24, 2006, 7:10am UTC](https://www.ruby-forum.com/t/everythings-an-object-right/72674/5 "2006-02-24T07:10:02Z")

</div>

\<\< … remember that assignment always “wipes out” the old reference.  
Assignment doesn’t change the old object at all. \>\>

Ah ha! I get it now.

Thanks!

---

<div class="post-metadata">

**Author:** ![Nathan\_Morse](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/3be4f8/32.png) [@Nathan\_Morse](https://www.ruby-forum.com/u/Nathan_Morse)\
**Post date:** [February 24, 2006, 11:30am UTC](https://www.ruby-forum.com/t/everythings-an-object-right/72674/6 "2006-02-24T11:30:07Z")

</div>

To the best of my knowledge everything (apart from integers) is passed  
by  
reference. However, 99% of the time this doesn’t matter. In ‘pure OOP’  
programming, ‘messages’ are sent to ‘methods’ and they respond with new  
data. If you only ever use return values you won’t see inconsistent  
behaviour and you won’t break encapsulation (which, in effect, using  
ByRef  
arguments to obtain new values does).

To clarify. There are a few string methods which alter the original  
string  
object. This is also the case if you index into a string to change a  
char.

However, when you evaluate an expression, this yields a new object so  
that  
in the following:

x = x + 1

The expression on the right yields a value which is assigned to a new  
object, x, on the left. In other words, the x on the right is a  
different  
object from the x on the left. Since methods which alter data usually do  
so  
in the process of evaluation and assignment, most of the time any object  
(such as x) which “goes in” is assigned to a new object (with the same  
name)  
by the time the method ends. This explains why many people believe that  
arguments are sent ‘by value’ - because, in most cases, the value of any  
argument that goes into a method is not changed. Rather, a new object is  
created during the process of evaluation and assignment.

If this is confusing, just stick to the ‘pure OOP’ way of doing things  
and  
always use return values; never try to use the values of ingoing  
arguments  
as ‘ByRef’ parameters. Life is much simpler that way 😉

# best wishes Huw C.

# Bitwise Magazine [www.bitwisemag.com](http://www.bitwisemag.com) Dark Neon Ltd.

---

<div class="post-metadata">

**Author:** ![Nathan\_Morse](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/n/3be4f8/32.png) [@Nathan\_Morse](https://www.ruby-forum.com/u/Nathan_Morse)\
**Post date:** [February 24, 2006, 2:24pm UTC](https://www.ruby-forum.com/t/everythings-an-object-right/72674/7 "2006-02-24T14:24:12Z")

</div>

Hi –

On Fri, 24 Feb 2006, Huw C. wrote:

> To the best of my knowledge everything (apart from integers) is passed by  
> reference.

Have a look at Hal’s post: it’s more a question of passing by value,  
where the values happen to be references. For example:

a = “hi”  
meth(a)

you’re actually passing the value of a – which is a reference to the  
string that was assigned to a.

If you use a literal construct as the argument:

meth(“hi”)

then it will be wrapped in a reference for the occasion.

> in the following:  
> argument that goes into a method is not changed. Rather, a new object is  
> created during the process of evaluation and assignment.
> 
> If this is confusing, just stick to the ‘pure OOP’ way of doing things and  
> always use return values; never try to use the values of ingoing arguments  
> as ‘ByRef’ parameters. Life is much simpler that way 😉

Except that it takes you right back to the original problem – namely,  
not understanding why the “values” you’re manipulating are actually  
behaving like references 🙂

I’d discourage splitting the matter into the simple part and the  
confusing part. It’s all reasonably simple, and certainly internally  
consistent – and it’s good to know what’s actually happening, partly  
to avoid (or at least explain) unexpected errors, and partly to have  
as large a technique kit as possible should this or that need arise.

David

–  
David A. Black (removed\_email\_address@domain.invalid)  
Ruby Power and Light ([http://www.rubypowerandlight.com](http://www.rubypowerandlight.com))

“Ruby for Rails” chapters now available  
from Manning Early Access Program! [Ruby for Rails](http://www.manning.com/books/black)
