0

Let's use this class definition as an example:

class Person
  def fname
    @fname
  end
  def fname=(fname)
    @fname = fname
  end
  def lname
    @lname
  end
  def lname=(lname)
    @lname = lname
  end
end

Just trying to connect the dots between Ruby and C++ syntax for example.

stanigator
  • 10,768
  • 34
  • 94
  • 129

1 Answers1

2

Yes, @foo-ish variables are instance variables.

Note the above can be shortened to:

class Person
  attr_accessor :fname, :lname
end
Dave Newton
  • 158,873
  • 26
  • 254
  • 302
  • So the moment I declared `attr_accessor :fname, :lname`, I've already made member instance variables? – stanigator May 13 '12 at 23:58
  • @stanigator: No, you haven't. Instance variables are created dynamically. In other words: they spring into existence automagically when they are first assigned. In the above two code snippets, `@fname` will only be created once `Person#fname=` is called the first time. It won't even be created when you call `Person#fname`. It will just return `nil` because initialized variables evaluate to `nil` in Ruby. – Jörg W Mittag May 14 '12 at 00:38
  • @JörgWMittag: I meant whether the instance variables of fname and lname when the script dynamically instantiates an object of the same class. Thanks for explaining the execution flow though. – stanigator May 14 '12 at 00:40
  • @stanigator I did deliberately over-simplify; Jörg is correct--instantiation also doesn't create the instance variables. – Dave Newton May 14 '12 at 00:57
  • Is it more correct to say instantiation creates an instance of the class which contains those member variables by default already? – stanigator May 14 '12 at 01:12
  • @stanigator No; instantiation creates an instance of the class--period. The instance variables don't exist until they're accessed, AFAIK. It'll just be `nil` until it's set. You'd need to dig into the C internals to know for sure--that's why I said "essentially" :) – Dave Newton May 14 '12 at 01:17
  • @JörgWMittag Did you mean "It will just return nil because *uninitialized* variables evaluate to nil in Ruby."? – Andrew Grimm May 14 '12 at 22:53
  • @stanigator: Instance variables are created when they are first assigned. Allocating ("instantiating" is another one of those dangerous words … usually it implies a constructor, but Ruby doesn't have constructors) a class simply creates an empty object. In fact, if you allocate a `Foo`, a `Bar`, a `Hash`, a `String` and an `Array`, those 5 objects will be pretty much bit-identical *except* for the class pointer. When an object is allocated, it really is completely empty. Think about it this way: instance variables aren't declared anywhere, so how the heck *could* the interpreter create them? – Jörg W Mittag May 15 '12 at 01:32
  • And yes, this means that every instance variable access potentially is a hash table lookup as opposed to say Java or C++ where instance variables are statically known at compile time and can thus be located at fixed offsets from the object header and only incur a direct pointer access. However, it is possible to do some performance optimization: you could leave space for 3 instance variables in the object header, scan the class for a method named `initialize` and special case the first three instance variable assignments you find there. (In fact, I believe that's exactly what YARV does.) – Jörg W Mittag May 15 '12 at 01:38
  • @JörgWMittag The instance variables really, truly belong to the instance, not the class or an eigenclass, right? – Andrew Grimm May 15 '12 at 01:44
  • @AndrewGrimm: Yes, exactly. This means that, unlike Java or C++, two instances of the same class need not have the same memory layout or shape. E.g.: `one = Foo.new; two = Foo.new; one.instance_variable_set(:@bar, 42)`. – Jörg W Mittag May 15 '12 at 01:47