如何检查ruby类中是否分配了实例变量?

时间:2015-07-14 21:31:10

标签: ruby-on-rails ruby rubygems

我有以下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

1 个答案:

答案 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中,因为变量不是对象,你只能将对象作为参数)。值得庆幸的是,有很多这样的方法:

[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 未定义,但这些问题超出了此问题的范围。]