Pour développer le titre: comment puis-je accéder à une variable d'instance ( @ivar
) d'une manière qui entraîne une exception si la variable d'instance n'a pas été initialisée?
3 Réponses :
Si vous voulez dire que h [k]
est la forme simple de h.fetch (k)
alors par analogique:
@ivar instance_variable_get(:@ivar)
La méthode instance_variable_get
fournit un accès arbitraire aux variables d'instance.
La différence ici est que h [k]
appelle Hash # []
qui renvoie nil code> si aucune clé n'est trouvée, tandis que
h.fetch (k)
appelle Hash # fetch
et lève une exception si la clé n'est pas trouvée . Cette différence est suffisamment importante pour être notée ici.
Cependant, aucune méthode intégrée ne fournit cette fonctionnalité en ce qui concerne les variables d'instance;
Puisque Hash # []
est analogue à @ivar
(ou instance_variable_get (: @ ivar)
) dans votre exemple, alors Hash # fetch
serait analogue à
@var = 42 instance_variable_fetch(:@var) #=> 42 @ivar = nil instance_variable_fetch(:@ivar) #=> nil instance_variable_fetch(:@other_var) #=> NameError: instance variable not found: @other_var
Exemple:
def instance_variable_fetch(sym) raise(NameError, "instance variable not found: #{sym}") unless instance_variable_defined?(sym) instance_variable_get(sym) end
Pour ce faire, je pense que vous auriez besoin d'accéder à la valeur de la variable d'instance, à partir de la classe, via un getter exclusivement. Le getter pourrait être rendu privé.
i = C.new i.instance_variables #=> [] i.ivar #=> RuntimeError (@ivar has not been set) i.instance_variable_get(:@ivar) #=> RuntimeError (@ivar has not been set) i.tell_ivar #=> RuntimeError (@ivar has not been set) i.ivar = 'cat' i.instance_variables #=> [:@ivar] i.ivar #=> "cat" i.instance_variable_get(:@ivar) #=> "cat" i.tell_ivar # cat is the value of @ivar
class C attr_writer :ivar alias :o_instance_variable_get :instance_variable_get def ivar givar end def instance_variable_get(v) (v==:@ivar || v=="@ivar") ? givar : o_instance_variable_get(v) end def tell_ivar puts "#{givar} is the value of @ivar" end private def givar raise RuntimeError, "@ivar has not been set" unless instance_variables.include?(:@ivar) @ivar end end
La méthode de lecture (publique) ivar
peut être supprimé s'il n'est pas souhaité.
@ivar
renverra nil
indépendamment du fait qu'il n'ait pas été défini ou qu'il ait été initialisé à nil
. De même, Object # instance_variable_get renvoie nil
si la variable d'instance n'a pas été définie ou nil
est sa valeur actuelle. i.instance_variables.include (: @ ivar)
est le seul moyen auquel je pourrais penser pour déterminer si @ivar
a été défini, éventuellement égal à nil code>.