Não precisa atribuir a variável de instância @name antes dos métodos, isto porque em Ruby existem algumas premissas muito importantes quando estiver lidando com POO:
- tudo é objeto, inclusive classes
- toda chamada a um objeto se dá por meio de métodos, nunca diretamente na variável de instância (exceto por metaprogramação). Isto faz com que o encapsulamento seja algo default em Ruby, e se quiser expor sua variável, terá que ser através de “getter” e “setter” como você fez
- o famoso self. Atribuições a variáveis ou métodos sejam de qualquer tipo (instância, classe, etc) são definidas no contexto léxico da linguagem, ou seja, se você define
@name dentro do método de instância, ela será atribuída no self de qualquer instância (objeto criado a partir da classe). Se você definir fora do método, que é o motivo da sua pergunta, a variável será atribuída ao contexto no qual ela está inserida: no self classe.
A última premissa acima é a mais difícil de absorver e é a resposta pra sua pergunta, mas uma vez entendido, você vai entender POO em Ruby. Entender o self e o contexto léxico (contexto de objetos, classes) é muito importante.
Pra visualizar isto, faça o teste. Atribua @name = "qualquer coisa" fora do método, depois crie um “método de classe” e imprima o valor de @name.
class Person
@name = "Class name"
### omitido restante do código
# define getter pra variável de instância da classe definida lá em cima
def self.my_class_name
@name
end
# define método de classe que vai imprimir a chamada ao método de classe **my_class_name**
def self.show_class_instance_variable
puts self.my_class_name
puts @name # alternativa, seria a mesma coisa, aqui ele vai imprimir a variável de instância da classe "Class name"
end
end
p = Person.new
p.name = "Object name"
p.show # imprime "Object name"
Person.show_class_variable_name # imprime "Class name"
Realmente POO em Ruby é um pouco diferente do que em Java, embora existem algumas semelhanças. Pra entender melhor, sugiro a leitura do capítulo 4 da apostila de Ruby on Rails da Caelum.