append des atsortingbuts à un object Ruby de manière dynamic

J’ai un object créé, et je souhaite, en fonction d’une vérification conditionnelle, append des atsortingbuts à cet object. Comment puis-je faire ceci? Pour expliquer ce que je veux:

A=Object.new if(something happens) { #make A have another attibute say age #& store something in A.age } 

Tout d’abord, Ruby permet une syntaxe différente, largement utilisée par les codeurs Ruby. Les identifiants en majuscules sont Classes ou Constants (merci à sepp2k pour son commentaire), mais vous essayez d’en faire un object. Et presque personne n’utilise {} pour marquer un bloc multiligne.

 a = Object.new if (something happens) # do something end 

Je ne suis pas sûr de votre question, mais j’ai une idée, et ce serait la solution:

Si vous savez quels atsortingbuts cette classe peut avoir, et que ceux-ci sont limités, vous devez utiliser

 class YourClass attr_accessor :age end 

attr_accessor :age est court pour:

 def age @age end def age=(new_age) @age = new_age end 

Maintenant, vous pouvez faire quelque chose comme ceci:

 a = YourClass.new if (some condition) a.age = new_value end 

Si vous voulez le faire complètement dynamic, vous pouvez faire quelque chose comme ceci:

 a = Object.new if (some condition) a.class.module_eval { attr_accessor :age} a.age = new_age_value end 

Cela ajoute l’atsortingbut uniquement à l’object:

 a = Object.new if (something happens) class << a attr_accessor :age end a.age = new_age_value end 

Vous pouvez utiliser un OpenStruct:

 a = OpenStruct.new if condition a.age = 4 end 

Ou utilisez simplement un vieux hash simple.

Si le nom de l’atsortingbut est connu au moment de l’écriture du code, vous pouvez faire ce qui a déjà été suggéré:

 class A end a = A.new a.age = 20 # Raises undefined method `age=' # Inject atsortingbute accessors into instance of A class << a attr_accessor :age end a.age = 20 # Succeeds a.age # Returns 20 b = A.new b.age # Raises undefined method, as expected, since we only modified one instance of A 

Cependant, si le nom de l'atsortingbut est dynamic et connu uniquement à l'exécution, vous devrez appeler un peu différemment attr_accessor :

 attr_name = 'foo' class A end a = A.new a.foo = 20 # Raises undefined method `foo=' # Inject atsortingbute accessors into instance of A a.instance_eval { class << self; self end }.send(:attr_accessor, attr_name) a.foo = 20 # Succeeds a.foo # Returns 20 

Vous pouvez utiliser instance_variable_set pour définir une variable sur une instance de la classe Object (et instance_variable_get pour l’obtenir). La classe Object ne possède aucun atsortingbut que vous pouvez définir directement.

Cependant, je soupçonne que ce n’est pas la meilleure solution pour ce que vous essayez d’atteindre; ce n’est pas la norme de travailler directement avec la classe Object, mais plutôt de définir ou d’utiliser des classes qui en héritent, avec les atsortingbuts avec lesquels vous voulez travailler.

 class Person; end person = Person.new person.age # throws NoMethodError if true person.singleton_class.module_eval { attr_accessor :age } end person.age = 123 person.age #=> 123 person2 = Person.new person2.age #=> throws NoMethodError