Method vs variable assigment

I can’t understand why this script

| #!/usr/bin/ruby
| class A
| attr_accessor :v
|
| def test
| p @v
| end
|
| def mod_explicit_setter
| self.v = “explicit setter”
| end
|
| def mod_setter
| v = “setter”
| end
|
| def mod_direct
| @v = “direct”
| end
| end
|
| a = A.new
| p a.methods - Object.new.methods
|
| a.mod_setter; a.test
| a.mod_direct; a.test
| a.mod_setter; a.test
| a.mod_explicit_setter; a.test

have this output

| [“mod_setter”, “mod_direct”, “v”, “v=”, “mod_explicit_setter”, “test”]
| ./vm.rb:7: warning: instance variable @v not initialized
| nil <- correct, v is a local variable
| “direct” <- correct
| “direct” <- correct? v= is an already seen method
| “explicit setter” <- correct

I thought that, once ruby sees a methods, it prefers to call that method
instead of creating a new local variable.

Hi –

On Sun, 23 Apr 2006, Gioele B. wrote:

| def mod_explicit_setter
| end

| [“mod_setter”, “mod_direct”, “v”, “v=”, “mod_explicit_setter”, “test”]
| ./vm.rb:7: warning: instance variable @v not initialized
| nil ← correct, v is a local variable
| “direct” ← correct
| “direct” ← correct? v= is an already seen method
| “explicit setter” ← correct

I thought that, once ruby sees a methods, it prefers to call that method
instead of creating a new local variable.

No; actually whenever it sees this:

var = value

it assumes that var is a local variable. So for methods ending in =
you get the syntactic sugar on the right (= instead of .=()) but not
on the left (you have to indicate the receiver explicitly).

David


David A. Black ([email protected])
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

“Ruby for Rails” PDF now on sale! Ruby for Rails
Paper version coming in early May!