7
votes

Mise arguments du constructeur en variables d'instance

Possible en double: strong> création d'objet idiomatiques en rubis p>

Il y a beaucoup de occaisions quand j'ai une méthode initialize code> qui ressemble à ceci: p>

class Foo
    attr_constructor :foo, :bar, :buz
end

p Foo.new('a', 'b', 'c')      # => #<Foo:0x93f3e4c @foo="a", @bar="b", @buz="c">
p Foo.new('a', 'b', 'c', 'd') # => #<Foo:0x93f3e4d @foo="a", @bar="b", @buz="c">
p Foo.new('a', 'b')           # => #<Foo:0x93f3e4e @foo="a", @bar="b", @buz=nil>


3 commentaires

Voulez-vous initialiser les attributs lors de la création?


Je pense que cette question a déjà été posée, mais je n'ai pas trouvé de doublons exacts.


@AndrewGrimm Merci pour se référant à la double question. Je verrai les réponses là-bas. Je vais voter pour fermer moi-même.


3 Réponses :


2
votes

Would ce travail pour vous?

class Foo  
    def initialize(hash)
        hash.each { |k,v| instance_variable_set("@#{k}", v) }
    end
end


1 commentaires

Ce n'est pas exactement ce que je veux. Je veux une méthode de classe à utiliser une fois dans le corps de la classe, qui contrôle le comportement de initialiser .



3
votes

J'utilise OpenStruct code> :

class Foo   
  def initialize(*args)
    @baz, @buz = args
  end
end


3 commentaires

Dans votre code, vous devez spécifier le nom de la variable d'instance à la construction, ce qui est pire que tout définir que dans le initialize méthode .


L'édition semble très élégante, mais cela ne semble pas fonctionner pour moi. f.baz etc jette des erreurs.


Vous devez ajouter attr_accessor si vous souhaitez que l'attribut soit lu / écritable à l'extérieur, tout comme normal



2
votes

question intéressante. Un peu de méta-programmation devrait s'en occuper.

f = Foo.new(:bar => 'One', :baz => 'Two')


1 commentaires

Merci pour la réponse, mais la nécessité d'écrire la ligne inclure des attraists chaque fois semble désagréable pour moi. Et, je n'ai pas nécessairement besoin attr_accessor s.