2
votes

hash [key] est de hash.fetch (key) comme @ivar est de quoi?

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?


0 commentaires

3 Réponses :


1
votes

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.


0 commentaires

5
votes

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 


0 commentaires

1
votes

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>.


0 commentaires