hash[key] 是 hash.fetch(key) 就像 @ivar 是什么?
hash[key] is to hash.fetch(key) as @ivar is to what?
扩展标题:如果实例变量尚未初始化,如何以导致异常的方式访问实例变量 (@ivar
)?
如果您的意思是 h[k]
是 h.fetch(k)
的简单形式,那么通过模拟:
@ivar
instance_variable_get(:@ivar)
instance_variable_get
方法提供对实例变量的任意访问。
这里的区别是 h[k]
调用 Hash#[]
如果没有找到密钥 returns nil
,而 h.fetch(k)
调用 Hash#fetch
并且 如果找不到密钥则引发异常 。这种差异非常重要,需要在此处注明。
然而,没有提供与实例变量有关的此功能的内置方法;
由于 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
要做到这一点,我相信您需要从 class 通过 getter 访问实例变量的值。 getter 可以设为私有。
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
(public) getter 方法 ivar
如果不需要,可以删除。
@ivar
将return nil
无论是否未定义或已初始化为 nil
。同样,如果实例变量没有被定义或者nil
是它的当前值,则Object#instance_variable_get returns nil
。 i.instance_variables.include(:@ivar)
是我能想到的唯一方法来确定 @ivar
是否已被定义,可能等于 nil
。
扩展标题:如果实例变量尚未初始化,如何以导致异常的方式访问实例变量 (@ivar
)?
如果您的意思是 h[k]
是 h.fetch(k)
的简单形式,那么通过模拟:
@ivar
instance_variable_get(:@ivar)
instance_variable_get
方法提供对实例变量的任意访问。
这里的区别是 h[k]
调用 Hash#[]
如果没有找到密钥 returns nil
,而 h.fetch(k)
调用 Hash#fetch
并且 如果找不到密钥则引发异常 。这种差异非常重要,需要在此处注明。
然而,没有提供与实例变量有关的此功能的内置方法;
由于 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
要做到这一点,我相信您需要从 class 通过 getter 访问实例变量的值。 getter 可以设为私有。
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
(public) getter 方法 ivar
如果不需要,可以删除。
@ivar
将return nil
无论是否未定义或已初始化为 nil
。同样,如果实例变量没有被定义或者nil
是它的当前值,则Object#instance_variable_get returns nil
。 i.instance_variables.include(:@ivar)
是我能想到的唯一方法来确定 @ivar
是否已被定义,可能等于 nil
。