Ruby variable scope

ruby, scope

Solution

When you declare the `@notes` within the class but not in the constructor or any of the instance methods, then you are making `@notes` an instance variable of the instance of the class itself. Every class exists as an instance of `Class` too.

class Notes
  @notes = ["Pick up some milk"]

      def print_notes
        puts @notes
      end
  end
# => nil
Notes.instance_variable_get(:"@notes")
# => ["Pick up some milk"]

So the answer is yes, you do need to declare the instance variable within the constructor or some other instance method. I think you'd prefer to do this:

class Notes
  def notes
    @notes ||= []
  end

  def print_notes
    puts @notes
  end
end

note = Notes.new
note.notes << "Pick up some milk"
note.notes
# => ["Pick up some milk"]

In addition:

Just avoid class variables e.g. `@@notes`. Use class instance variables instead (which is what you unwittingly did).

Do this:

class Notes
  def self.notes
    @notes ||= []
  end
end

not this:

class Notes
  def notes
    @@notes ||= []
  end
end

when you want a class variable. The latter will cause you problems down the road. (But I think this is something for a different conversation.)

Problem

I've been looking at learning a new dynamic scripting language for web development and after agonising over Python and Ruby, as I really liked both, I've decided to pick Ruby (It pretty much came down to a coin toss and the fact there are more RoR jobs in the UK than Python/Django). My question is about scope in Ruby. Do I have to declare a class attribute inside a method to be able to access it from other methods? For example, I cannot do ``` class Notes @notes = ["Pick up some milk"] def print_notes puts @notes end end ``` It seems I have to declare attributes I want to use in the constructor? This example works: ``` class Notes def initialize @notes = ["Pick up some milk"] end def print_notes puts @notes end end ``` Is this right? I've noticed prefixing example one with @@ instead of @ works but to my understanding if the class has a subclass (say, Memo) then any changes to attributes prefixed with @@ in Notes would change the value in Memo? Sorry if this is a repeat question, just a lost noobie :)

Original source