2017-08-21 2 views
1

Je veux savoir comment créer attr_accessor à la volée. Est-il possible de faire quelque chose comme:Ruby: Comment créer attr_accessor à la volée

attr_accessor "@#{key}" 

dans la méthode d'initialisation?

module Mymodule 
    def initialize(parameters = {}) 
    parameters.each do |key, value| 
     instance_variable_set("@#{key}", value) unless value.nil? 
    end 
    end 
end 

class Myclass 
    include Mymodule 
end 

clazz = Myclass.new attr1: "Arg1", attr2: "Arg2", attr3: "Arg3" 
    # => #<Myclass:0x43f6050 @attr1="Arg1", @attr2="Arg2", @attr3="Arg3"> 

clazz.attr1 
    # !> NoMethodError: undefined method `attr1' for #<Myclass:0x43f6050 @attr1="Arg1", @attr2="Arg2", @attr3="Arg3"> 

clazz.attr1="ATTR1" 
    # !> NoMethodError: undefined method `attr1=' for #<Myclass:0x43f6050 @attr1="Arg1", @attr2="Arg2", @attr3="Arg3"> 

Répondre

5

Vous pouvez définir par exemple accesseurs en appelant attr_accessor la classe singleton de cette instance.

class Structy 
    def initialize(parameters = {}) 
    parameters.each do |key, value| 
     singleton_class.send :attr_accessor, key 
     instance_variable_set "@#{key}", value 
    end 
    end 
end 
+0

Cela fonctionne. Merci beaucoup. –

+0

@JulioCarvalho Il y a aussi ['Struct'] (https://ruby-doc.org/core/Struct.html) et [' OpenStruct'] (https://ruby-doc.org/stdlib/libdoc/ ostruct/rdoc/OpenStruct.html) classes en standard Ruby. Souvent, ces classes sont utiles pour construire des structures. Dans tous les cas, vous devez faire attention aux bordures ici, par ex. lorsque vous définissez des clés spéciales comme ': hash',': to_s' ou ': inspect' qui peuvent masquer des méthodes sur lesquelles vous pouvez vous appuyer implicitement pour se comporter comme leur implémentation standard. Vérifiez les problèmes de sécurité subtils lors de l'autorisation des paramètres fournis par l'utilisateur. –