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