1
 class Sample
   attr_accessor :x,:y

   def initialize 
     @x = "x"
     y = "y"     
   end
 end     

 Sample.new.instance_variables  => [:@x] 

class Sample
  attr_accessor :x,:y

  def initialize 
     @x = "x"
     self.y = "y"     
  end
end  

Sample.new.instance_variables => [:@x, :@y] 

Can anyone let me know what is going on here. Why is y an instance_variable second time?

Phani
  • 1,704
  • 3
  • 13
  • 18
  • 1
    In first sample, if you assign : `@y=1` , then you shall get `@y` as ivar as well. I surmise Ruby is optimizing in the `attr_accessor`, and not creating an ivar until you specifically assign to it. – Zabba Feb 01 '13 at 07:00
  • and @Zabba : A variable does not exist until you assign a value to it. Please see http://stackoverflow.com/questions/13850971/why-are-symbols-in-ruby-not-thought-of-as-a-type-of-variable/13861177#13861177 – BernardK Feb 01 '13 at 08:04

3 Answers3

8

attr_accessor :y defines methods that are roughly equivalent to

def y
  @y
end

def y=(val)
  @y = val
end

So, when you assign to self.y, you are assigning to an instance variable due to the attr_accessor macro

Jim Deville
  • 10,632
  • 1
  • 37
  • 47
1

Why not? self is an instance and y is an instance var. In the first example, y is only a normal local var.

halfelf
  • 9,737
  • 13
  • 54
  • 63
1

This line

attr_accessor :y

creates a couple of methods

def y
  @y
end

def y= val
  @y = val
end

So, when you call y= method, @y instance variable jumps to life. In second snippet you correctly call y= method. But in the first one you simply create an unused local variable y (setter method is not called and ivar is not created).

Sergio Tulentsev
  • 226,338
  • 43
  • 373
  • 367
  • 1
    It's important to note that historically `attr_accessor` will benchmark faster than these equivalent methods, they're C-based optimizations instead of executable code, so whenever possible you should use the `attr_` declarations instead of writing your own. – tadman Feb 01 '13 at 07:44