hash [ключ] - это hash.fetch (ключ), как @ivar для чего? - PullRequest
0 голосов
/ 21 января 2019

Чтобы расширить заголовок: Как я могу получить доступ к переменной экземпляра (@ivar) таким образом, что это приведет к исключению, если переменная экземпляра не была инициализирована?

Ответы [ 3 ]

0 голосов
/ 21 января 2019

Однако нет встроенного метода, обеспечивающего эту функциональность в отношении переменных экземпляра;

Поскольку Hash#[] аналогичен @ivar (или instance_variable_get(:@ivar)) в вашем примере, то Hash#fetchбудет аналогично

def instance_variable_fetch(sym)
  raise(NameError, "instance variable not found: #{sym}") unless instance_variable_defined?(sym) 
  instance_variable_get(sym)
end 

Пример:

@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
0 голосов
/ 22 января 2019

Я полагаю, что для этого вам понадобится получить доступ к значению переменной экземпляра из класса исключительно через геттер.Получатель может быть закрытым.

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

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 

(общий) метод получения ivar может быть удален, если он не нужен.

@ivar вернет nil независимо от того, было ли оно определено или было инициализировано в nil.Аналогично, Object # instance_variable_get возвращает nil, если переменная экземпляра не была определена или nil является ее текущим значением.i.instance_variables.include(:@ivar) - это единственный способ определить, было ли определено @ivar, возможно, равное nil.

0 голосов
/ 21 января 2019

Если вы имеете в виду h[k] - это простая форма h.fetch(k), то по аналогу:

@ivar
instance_variable_get(:@ivar)

Метод instance_variable_get обеспечивает произвольный доступ к переменным экземпляра.

Разница в том, что h[k] вызывает Hash#[], который возвращает nil, если ключ не найден, тогда как h.fetch(k) вызывает Hash#fetch и вызывает исключение, если ключ не найден, Это различие достаточно важно, чтобы отметить здесь.

...