# Can't change the value of self

**URL:** <https://www.ruby-forum.com/t/cant-change-the-value-of-self/51509>\
**Category:** Ruby\
**Created:** [January 2, 2006, 1:39am UTC](https://www.ruby-forum.com/t/cant-change-the-value-of-self/51509 "2006-01-02T01:39:36Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![johanatan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8491ac/32.png) [@johanatan](https://www.ruby-forum.com/u/johanatan)\
**Post date:** [January 2, 2006, 1:39am UTC](https://www.ruby-forum.com/t/cant-change-the-value-of-self/51509/1 "2006-01-02T01:39:36Z")

</div>

This code:

* * *

class Time

# Rounds a time sensibly.

# Currently just hour is supported (as that’s the only one needed)

def round\_to(unit = :hour)  
unless min == 0  
new\_hour = hour  
new\_hour += 1 if min \> 30  
time = Time.local(year, month, day, new\_hour)  
end  
time  
end

def round\_to!(\*args)  
self = round\_to \*args  
end

## end

Throws this error:

Can’t change the value of self (SyntaxError)  
self = round\_to \*args

Why doesn’t it work? What can I do instead?

Thanks

---

<div class="post-metadata">

**Author:** ![johanatan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8491ac/32.png) [@johanatan](https://www.ruby-forum.com/u/johanatan)\
**Post date:** [January 2, 2006, 1:42am UTC](https://www.ruby-forum.com/t/cant-change-the-value-of-self/51509/2 "2006-01-02T01:42:38Z")

</div>

Jonathan L. wrote:

> Can’t change the value of self (SyntaxError)  
> self = round\_to \*args
> 
> Why doesn’t it work? What can I do instead?

“Destructive” methods must alter self using that self’s existing  
destructive methods.

James

–

[http://www.ruby-doc.org](http://www.ruby-doc.org) - Ruby Help & Documentation  
[Ruby Code & Style](http://www.artima.com/rubycs/) - Ruby Code & Style: Writers wanted  
[http://www.rubystuff.com](http://www.rubystuff.com) - The Ruby Store for Ruby Stuff  
[http://www.jamesbritt.com](http://www.jamesbritt.com) - Playing with Better Toys  
[http://www.30secondrule.com](http://www.30secondrule.com) - Building Better Tools

---

<div class="post-metadata">

**Author:** ![johanatan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8491ac/32.png) [@johanatan](https://www.ruby-forum.com/u/johanatan)\
**Post date:** [January 2, 2006, 1:48am UTC](https://www.ruby-forum.com/t/cant-change-the-value-of-self/51509/3 "2006-01-02T01:48:39Z")

</div>

James B. wrote:

> Jonathan L. wrote:
> 
> > Can’t change the value of self (SyntaxError)  
> > self = round\_to \*args
> > 
> > Why doesn’t it work? What can I do instead?
> 
> “Destructive” methods must alter self using that self’s existing  
> destructive methods.

To which we should add: Time has no destructive methods, since  
Time objects are immutable.

But someone once created a MutableTime class – anyone recall  
who/when/where and whether it’s complete?

Hal

---

<div class="post-metadata">

**Author:** ![johanatan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8491ac/32.png) [@johanatan](https://www.ruby-forum.com/u/johanatan)\
**Post date:** [January 2, 2006, 2:12am UTC](https://www.ruby-forum.com/t/cant-change-the-value-of-self/51509/4 "2006-01-02T02:12:58Z")

</div>

On Mon, 2006-01-02 at 09:47 +0900, Hal F. wrote:

> > destructive methods.
> 
> To which we should add: Time has no destructive methods, since  
> Time objects are immutable.
> 
> But someone once created a MutableTime class – anyone recall  
> who/when/where and whether it’s complete?

Thanks for the replies. Why is Time immutable (presumably it’s  
deliberately designed like that)? The MutableTime class sounds  
interesting but it’s probably overkill for what I wanted to do – I’ll  
just modify variables at a higher level.

Thanks

---

<div class="post-metadata">

**Author:** ![johanatan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8491ac/32.png) [@johanatan](https://www.ruby-forum.com/u/johanatan)\
**Post date:** [January 2, 2006, 4:22am UTC](https://www.ruby-forum.com/t/cant-change-the-value-of-self/51509/5 "2006-01-02T04:22:12Z")

</div>

On 1/1/06, Hal F. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > destructive methods.
> 
> To which we should add: Time has no destructive methods, since  
> Time objects are immutable.
> 
> But someone once created a MutableTime class – anyone recall  
> who/when/where and whether it’s complete?

This is why I can’t do:  
class Fixnum  
def double!  
self \*= 2  
end  
end  
…right? Too bad.

Speaking of methods… is there a way to do:  
class Something  
def \<\<(a, b)  
# do something with a and b  
end  
end

s = Something.new  
s \<\< ‘a’, ‘b’  
results in a syntax error.

Is that another of those YACC limitations?

---

<div class="post-metadata">

**Author:** ![johanatan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8491ac/32.png) [@johanatan](https://www.ruby-forum.com/u/johanatan)\
**Post date:** [January 2, 2006, 2:19am UTC](https://www.ruby-forum.com/t/cant-change-the-value-of-self/51509/6 "2006-01-02T02:19:01Z")

</div>

On Jan 1, 2006, at 7:37 PM, Jonathan L. wrote:

> Can’t change the value of self (SyntaxError)  
> self = round\_to \*args
> 
> Why doesn’t it work? What can I do instead?

Instead of

```
a.round_to!(:hour)

```

just write

```
a = a.round_to(:hour)

```

Or maybe a different name would help:

```
a = a.closest(:hour)

```

Gary W.

---

<div class="post-metadata">

**Author:** ![johanatan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8491ac/32.png) [@johanatan](https://www.ruby-forum.com/u/johanatan)\
**Post date:** [January 2, 2006, 5:16am UTC](https://www.ruby-forum.com/t/cant-change-the-value-of-self/51509/7 "2006-01-02T05:16:18Z")

</div>

Wilson B. wrote:

> …right? Too bad.

Well, that, and what would “2.double!” do?

> 

My guess is you’re out of luck, there. But you could change it to take s  
\<\< [‘a’,‘b’] or s \<\< ‘a’ \<\< ‘b’.

Devin

---

<div class="post-metadata">

**Author:** ![johanatan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8491ac/32.png) [@johanatan](https://www.ruby-forum.com/u/johanatan)\
**Post date:** [January 2, 2006, 8:23am UTC](https://www.ruby-forum.com/t/cant-change-the-value-of-self/51509/8 "2006-01-02T08:23:37Z")

</div>

Wilson B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) writes:

> 

You could do s.\<\<(‘a’, ‘b’), but it seems unrubyish. Perhaps you  
could settle for:

s \<\< [‘a’, ‘b’]

> Is that another of those YACC limitations?

Hmmm, I don’t know if it’s a limitation, but it could get confusing.  
Consider:

four, three = 1 \<\< 2, 3  
arr = [x \<\< 1, x \<\< 2]

And if you do it for `<<', then what about `+‘, `-', `%’? If you do  
do it for those, then you start to lose really basic stuff like:

arr = [a + 1, b + 1]  
b, a = a % b, b until b == 0

---

<div class="post-metadata">

**Author:** ![johanatan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8491ac/32.png) [@johanatan](https://www.ruby-forum.com/u/johanatan)\
**Post date:** [January 2, 2006, 1:06pm UTC](https://www.ruby-forum.com/t/cant-change-the-value-of-self/51509/9 "2006-01-02T13:06:59Z")

</div>

Thanks very much for this explanation, the restriction makes a lot more  
sense to me now.

Jon

---

<div class="post-metadata">

**Author:** ![johanatan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8491ac/32.png) [@johanatan](https://www.ruby-forum.com/u/johanatan)\
**Post date:** [January 2, 2006, 11:33am UTC](https://www.ruby-forum.com/t/cant-change-the-value-of-self/51509/10 "2006-01-02T11:33:27Z")

</div>

On Mon, 2 Jan 2006 09:37:45 +0900, Jonathan L.  
[removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> Can’t change the value of self (SyntaxError)  
> self = round\_to \*args
> 
> Why doesn’t it work? What can I do instead?

One way of thinking about reassigning self is if you imagine in a  
numeric class  
saying

def double  
self \*= 2  
end

That would amount to saying, if we did 1.double,  
1 becomes 2  
which would mean that 1+1 would thereafter be 4, and that would be bad.

What we need is not the value 1 to become 2, but to get the value 2 back  
when we  
say 1.double. So we say

def double  
return self\*2  
end

or, since “return” is implied

def double  
self\*2  
end

In general in OO, an object can change its contents, but it cannot  
change its  
“self”. What should happen in this program?

one = 1  
another\_one = 1  
assert\_equal(2, one+one)  
assert\_equal(2, another\_one+another\_one)  
one.double  
assert\_equal(4, one+one)  
assert\_equal(???,another\_one+another\_one)  
assert\_equal(???, 1+1)

When we double one, if the self\*=2 thing worked, the ??? asserts would  
also find  
4. We might be able to understand another\_one being 2, but to have all  
occurrences of 1+1 in the program turn into 4 … that would be bad.

Certain objects are called “value objects”, and the idea is that like  
numbers,  
they never change value. For many objects it is a design choice whether  
or not  
to make them value objects, even if they are quite complex. For example,  
in the  
articles I’m currently writing on extended set theory on my site, I’m  
moving in  
the direction of making my sets value objects. They are essentially  
arbitrarily  
large collections of records (like relational database relations), and  
most DB  
apps think of relations as mutable. I’m going to make a different  
decision,  
namely that any set, once created, is a constant. It’ll be interesting  
to see  
what happens.

---

<div class="post-metadata">

**Author:** ![johanatan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8491ac/32.png) [@johanatan](https://www.ruby-forum.com/u/johanatan)\
**Post date:** [January 2, 2006, 8:45pm UTC](https://www.ruby-forum.com/t/cant-change-the-value-of-self/51509/11 "2006-01-02T20:45:37Z")

</div>

Jonathan L. wrote:

> Thanks very much for this explanation, the restriction makes a lot more  
> sense to me now.

You should also know that more complex objects (as you know) can  
often change their state. In particular, Array and String both  
implement a replace method, which totally replaces their contents.  
But even then, the object id stays the same.

Hal

---

<div class="post-metadata">

**Author:** ![johanatan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8491ac/32.png) [@johanatan](https://www.ruby-forum.com/u/johanatan)\
**Post date:** [January 5, 2006, 2:33am UTC](https://www.ruby-forum.com/t/cant-change-the-value-of-self/51509/12 "2006-01-05T02:33:40Z")

</div>

Immutable classes are less prone to bugs than mutable classes. This is  
because they have a single state. They are also thread safe.

It is good practise to favor immutability when there are no compelling  
reasons for making a class mutable.

A Time object represents an instance in time. Making it mutable could  
easily get confusing. Consider:

time = MutableTime.at(946702800)  
rocket.launch\_time = time  
…  
time.change(946701565) # Changes the launch time of the rocket

The launch time of the rocket can be changed without setting the  
launch\_time property explicitly. This is a potential source of bugs.

/Henrik

---

<div class="post-metadata">

**Author:** ![johanatan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8491ac/32.png) [@johanatan](https://www.ruby-forum.com/u/johanatan)\
**Post date:** [January 5, 2006, 4:31am UTC](https://www.ruby-forum.com/t/cant-change-the-value-of-self/51509/13 "2006-01-05T04:31:09Z")

</div>

Henrik M. wrote:

> rocket.launch\_time = time  
> …  
> time.change(946701565) # Changes the launch time of the rocket
> 
> The launch time of the rocket can be changed without setting the  
> launch\_time property explicitly. This is a potential source of bugs.

Thanks, Henrik. That’s a great discussion and a great example.

Hal

---

<div class="post-metadata">

**Author:** ![johanatan](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/8491ac/32.png) [@johanatan](https://www.ruby-forum.com/u/johanatan)\
**Post date:** [January 5, 2006, 7:29am UTC](https://www.ruby-forum.com/t/cant-change-the-value-of-self/51509/14 "2006-01-05T07:29:12Z")

</div>

On Jan 1, 2006, at 5:47 PM, Hal F. wrote:

> Time objects are immutable.
> 
> But someone once created a MutableTime class – anyone recall  
> who/when/where and whether it’s complete?

That’d be me, and it’s documented at [RubyLibs on Phrogz](http://phrogz.net/RubyLibs/rdoc/)  
classes/MutableTime.html and available for download at http://  
[phrogz.net/RubyLibs/MutableTime.rb](http://phrogz.net/RubyLibs/MutableTime.rb)

As to whether it’s ‘complete’…I dunno. I nominally labeled it  
v1.0.5, but who knows what that means 🙂
