# Writable attributes - how does this work?

**URL:** <https://www.ruby-forum.com/t/writable-attributes-how-does-this-work/60227>\
**Category:** Ruby\
**Created:** [May 11, 2006, 11:13am UTC](https://www.ruby-forum.com/t/writable-attributes-how-does-this-work/60227 "2006-05-11T11:13:05Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Krekna\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/a9adbd/32.png) [@Krekna\_M](https://www.ruby-forum.com/u/Krekna_M)\
**Post date:** [May 11, 2006, 11:13am UTC](https://www.ruby-forum.com/t/writable-attributes-how-does-this-work/60227/1 "2006-05-11T11:13:05Z")

</div>

Hi!

How does this actually work?

from the Pick Axe book:

irb\>  
1\> class Song  
2 \> def duration=(new\_duration)  
3\> @duration = new\_duration  
4\> end  
5\> end  
6\>  
7\> song = Song.new(“Bicylops”, “Fleck”, 260)  
8\> song.duration --\> 260  
9\> song.duration = 257  
10\> song.duration --\> 257

If a method name which is used to set the attribute is called  
“duration=”, how come that one can use song.duration = 257?

I mean, does it just work lik this, because the Ruby engine recognizes  
the ‘set attribute’ method just because of the = sign after the  
“duration” on line number two?

Tnx,  
Krekna

---

<div class="post-metadata">

**Author:** ![Krekna\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/a9adbd/32.png) [@Krekna\_M](https://www.ruby-forum.com/u/Krekna_M)\
**Post date:** [May 11, 2006, 11:25am UTC](https://www.ruby-forum.com/t/writable-attributes-how-does-this-work/60227/2 "2006-05-11T11:25:13Z")

</div>

Krekna, your understanding is correct:

# 

> > x = Object.new  
> > =\> #Object:0x24870738  
> > x.aa = 10  
> > NoMethodError: undefined method `aa=’ for #Object:0x24870738

# 

note method name reported: ‘aa=’

Sergey

----- Original Message -----  
From: “Krekna M.” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
To: “ruby-talk ML” [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
Sent: Thursday, May 11, 2006 5:12 AM  
Subject: Writable attributes - how does this work?

Hi!

How does this actually work?

from the Pick Axe book:

irb\>  
1\> class Song  
2 \> def duration=(new\_duration)  
3\> @duration = new\_duration  
4\> end  
5\> end  
6\>  
7\> song = Song.new(“Bicylops”, “Fleck”, 260)  
8\> song.duration → 260  
9\> song.duration = 257  
10\> song.duration → 257

If a method name which is used to set the attribute is called  
“duration=”, how come that one can use song.duration = 257?

I mean, does it just work lik this, because the Ruby engine recognizes  
the ‘set attribute’ method just because of the = sign after the  
“duration” on line number two?

Tnx,  
Krekna

---

<div class="post-metadata">

**Author:** ![Krekna\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/a9adbd/32.png) [@Krekna\_M](https://www.ruby-forum.com/u/Krekna_M)\
**Post date:** [May 11, 2006, 11:28am UTC](https://www.ruby-forum.com/t/writable-attributes-how-does-this-work/60227/3 "2006-05-11T11:28:16Z")

</div>

> 6\>  
> “duration” on line number two?  
> You’ll probably get better answers from someone who is smarter than I  
> am,  
> but since it’s late and I’m waiting for something to finish, here’s how  
> I  
> think about it…

Stop thinking of =, ==, +, \*, \<=,… as operators. Think of them as  
methods.

So, when you see “a = b” that’s really saying call the method “=” on the  
object “a” passing as an argument “b”. If you think of it that way then  
when you see the below method it will make more sense.

def a= (b)  
@a = b  
end

So, “a + b” is really:

def a+ (b)  
return a + b  
end

(yes, I know the return is unecessary, just trying to be clear 🙂

Hope that helps.

---

<div class="post-metadata">

**Author:** ![Krekna\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/a9adbd/32.png) [@Krekna\_M](https://www.ruby-forum.com/u/Krekna_M)\
**Post date:** [May 11, 2006, 11:31am UTC](https://www.ruby-forum.com/t/writable-attributes-how-does-this-work/60227/4 "2006-05-11T11:31:29Z")

</div>

On 5/11/06, Krekna M. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> 4\> end  
> I mean, does it just work lik this, because the Ruby engine recognizes  
> the ‘set attribute’ method just because of the = sign after the  
> “duration” on line number two?

Yes! song.duration = 257 calls the duration= method in Song.  
It’s as if you wrote song.duration=(257)

You are not actually manipulating Song’s @duration directly.

---

<div class="post-metadata">

**Author:** ![Krekna\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/a9adbd/32.png) [@Krekna\_M](https://www.ruby-forum.com/u/Krekna_M)\
**Post date:** [May 11, 2006, 11:44am UTC](https://www.ruby-forum.com/t/writable-attributes-how-does-this-work/60227/5 "2006-05-11T11:44:10Z")

</div>

Its just passing 257 into the duration method via the new\_duration  
argument and putting it in the @duration attribute variable.

Krekna M. wrote:

> Hi!
> 
> How does this actually work?
> 
> from the Pick Axe book:
> 
> irb\>  
> 1\> class Song  
> 2 \> def duration=(new\_duration)  
> 3\> @duration = new\_duration

---

<div class="post-metadata">

**Author:** ![Krekna\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/a9adbd/32.png) [@Krekna\_M](https://www.ruby-forum.com/u/Krekna_M)\
**Post date:** [May 11, 2006, 11:58am UTC](https://www.ruby-forum.com/t/writable-attributes-how-does-this-work/60227/6 "2006-05-11T11:58:22Z")

</div>

works basically like

class\_name  
method\_name(argument\_name)  
@attribute\_name = argument\_name  
end  
end

so class\_name.method\_name = arguments to pass into argument\_name

Krekna M. wrote:

> Hi!
> 
> How does this actually work?
> 
> from the Pick Axe book:
> 
> irb\>

---

<div class="post-metadata">

**Author:** ![Krekna\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/a9adbd/32.png) [@Krekna\_M](https://www.ruby-forum.com/u/Krekna_M)\
**Post date:** [May 11, 2006, 2:16pm UTC](https://www.ruby-forum.com/t/writable-attributes-how-does-this-work/60227/7 "2006-05-11T14:16:15Z")

</div>

Thanx, it’s clear to me now. Thank you all for the quick answers, each  
supplementing each other.

Krekna

2006/5/11, corey konrad [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):

---

<div class="post-metadata">

**Author:** ![Krekna\_M](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/k/a9adbd/32.png) [@Krekna\_M](https://www.ruby-forum.com/u/Krekna_M)\
**Post date:** [May 11, 2006, 5:54pm UTC](https://www.ruby-forum.com/t/writable-attributes-how-does-this-work/60227/8 "2006-05-11T17:54:30Z")

</div>

On 5/11/06, Philip H. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> Stop thinking of =, ==, +, \*, \<=,… as operators. Think of them as  
> methods.

Correct. Usually. As seen below, = sometimes is just an operator.  
Others like ! are never methods. And some, like != and +=, are  
translated into multiple operators/methods. E.g.

# equivalent comparisons, you can’t override != directly

a != b  
!(a == b)  
!(a.==(b))

# equivalent method calls

foo.a += 1  
foo.a = foo.a + 1  
foo.a=(foo.a + 1)  
foo.a=(foo.a.+(1))

# equivalent assignments

a += 1  
a = a + 1  
a = a.+(1)

> So, when you see “a = b” that’s really saying call the method “=” on the  
> object “a” passing as an argument “b”. If you think of it that way then  
> when you see the below method it will make more sense.
> 
> def a= (b)  
> @a = b  
> end

Not quite correct.

The = is translated by the parser into a method call only if the left  
hand side has an explicit receiver:

# equivalent method calls

foo.a = b  
foo.a=(b)  
foo.send(:“a=”, b)

But if the left hand side has no explicit receiver, the = is simply an  
assignment operator to a local (or instance, or class instance)  
variable:

# direct assignments

a = 5  
@a = 5  
@@a = 5

> So, “a + b” is really:
> 
> def a+ (b)  
> return a + b  
> end

Also not quite correct. a + b _is_ always a method call, but the name  
of the method is just “+”. a is the receiver and b is the argument:

# equivalent method calls

a + b  
a.+(b)  
a.send(:“+”, b)

Even with an explicit receiver on the left hand side, it’s just a  
matter of a method call on the _value_ of the left hand side:

# equivalent method calls

foo.a + b  
foo.a.+(b)

# _not_ equivalent

foo.send(:“a+”, b)

As an aside, I don’t think there’s any syntax that would work for  
invoking a method named “a+” other than using a direct send.

Jacob F.
