Я полагаю, что для этого вам понадобится получить доступ к значению переменной экземпляра из класса исключительно через геттер.Получатель может быть закрытым.
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
.