2010-05-13 4 views
1

J'étudie Ruby et mon cerveau a juste gelé.Comment écrire une méthode writer pour une variable de classe dans Ruby?

Dans le code suivant, comment écrire la méthode d'écriture de classe pour 'self.total_people'? J'essaie de «compter» le nombre d'instances de la classe «Personne».

class Person 

    attr_accessor :name, :age 

@@nationalities = ['French', 'American', 'Colombian', 'Japanese', 'Russian', 'Peruvian'] 

@@current_people = [] 

@@total_people = 0 

def self.nationalities #reader 
    @@nationalities 
end 

def self.nationalities=(array=[]) #writer 
    @@nationalities = array 
end 

def self.current_people #reader 
    @@current_people 
end 

def self.total_people #reader 
    @@total_people 
end 

def self.total_people #writer 
    #-----????? 
end 



def self.create_with_attributes(name, age) 
    person = self.new(name) 
    person.age = age 
    person.name = name 
    return person 
end 


def initialize(name="Bob", age=0) 
    @name = name 
    @age = age 
    puts "A new person has been instantiated." 
    @@total_people =+ 1 
    @@current_people << self 
end 

Répondre

6

Vous pouvez définir un en annexant le signe égal à la fin du nom de la méthode:

def self.total_people=(v) 
    @@total_people = v 
end 

Vous mettez toutes les instances dans @@ current_people vous pouvez définir total_people plus précisément:

def self.total_people 
    @@current_people.length 
end 

Et de se débarrasser de tout le code lié @@ total_people.

0

Une approche qui ne fonctionne pas est la suivante:

module PersonClassAttributes 
    attr_writer :nationalities 
end 

class Person 
    extend PersonClassAttributes 
end 

Je soupçonne que c'est parce que attr_writer ne fonctionne pas avec des modules pour une raison quelconque.

Je voudrais savoir s'il y a un moyen de métaprogrammer cette approche. Cependant, avez-vous envisagé de créer un objet contenant une liste de personnes?

4

Je pense que cela résout votre problème:

class Person 
    class << self 
    attr_accessor :foobar 
    end 

    self.foobar = 'hello' 
end 

p Person.foobar # hello 

Person.foobar = 1 

p Person.foobar # 1 

Soyez au courant des variables avec gotchas de classe de Ruby avec l'héritage - des classes d'enfants ne peuvent pas passer outre la valeur du parent de la classe var. Un class instance variable peut vraiment être ce que vous voulez ici, et cette solution va dans cette direction.

Questions connexes