我有以下2个类的属性将在其他一些客户端类中设置。如果未分配这些类的实例变量,我想确保不在if
条件(例如if(@lte)
)内进行。我是否需要明确检查.empty?
,.nil?
或.blank?
等?什么建议检查未分配的实例变量?
# ==== range filter ====
class Range < QueryModel
query_hash = {}
attr_accessor :search_field, :range_criteria
def serialize
if(@search_field)
query_hash[@search_field] = @range_criteria.serialize
query_hash[:range] = self.query_hash
end
end
end
class RangeCriteria < QueryModel
query_hash = {}
attr_accessor :gte, :lte
def serialize
if(@gte)
query_hash[:gte] = @gte
end
if(@lte)
query_hash[:lte] = @lte
end
if(@gte != nil || @lte != nil)
return query_hash
end
end
end
答案 0 :(得分:2)
很明显,您无法通过解除引用变量来确定是否已分配变量。为什么?好吧,要么尝试取消引用尚未分配的变量将是一个错误(在这种情况下你的代码将中断),或者它将评估为某个默认对象,在这种情况下你将无法知道它是否被评估为对象,因为变量未分配或因为有人将该对象分配给该变量。
在Ruby中,两种情况都可能发生,具体取决于变量的类型:
object lineUnit = WdUnits.wdLine;
document.Range(document.Content.Start, document.Content.Start).Select();
// Word groks this happily
Globals.ThisAddIn.Application.Selection.Expand(ref lineUnit);
无论哪种方式,简单的逻辑告诉我们在变量上调用方法不能可能回答我们的问题。我们不能取消引用我们的变量以确定它是否已分配。我们必须寻找一些其他的方法,对于一些将变量作为参数的反射方法(更准确地说,它将变量的名称作为参数;方法不能将变量作为参数在Ruby中,因为变量不是对象,你只能将对象作为参数)。值得庆幸的是,有很多这样的方法:
Module#const_defined?
Module#class_variable_defined?
Binding#local_variable_defined?
Object#instance_variable_defined?
[BTW:请注意,全局变量没有相应的方法,我不知道为什么。]
在你的情况下,你显然想要后者:
UnassignedConstant.nil?
# Boom! NameError
@unassigned_instance_variable.nil?
# => true
# but is it true because it was unassigned or because someone assigned nil?
[请注意,您的代码还存在其他问题,例如def serialize
if instance_variable_defined?(:@gte)
query_hash[:gte] = @gte
end
if instance_variable_defined?(:@lte)
query_hash[:lte] = @lte
end
unless @gte.nil? && @lte.nil?
query_hash
end
end
未定义,但这些问题超出了此问题的范围。]