如何在ruby class中检查一个实例变量是否赋值?

How to check whether an instance variable is assigned or not in ruby class?

我有以下 2 classes 谁的属性将在其他一些客户端 class 中设置。如果这些 classes 的实例变量没有被赋值,我想确保我没有把它放在 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

您可以使用 .present?

基本和.empty?相反

.blank? 很常见,但请记住,空字符串和 false 将导致 true,这可能不是您想要的。在这种情况下,您可能需要使用 .nil? 或类似的。

> "".blank?
=> true
> false.blank?
=> true

很明显,您无法通过取消引用变量来确定变量是否已赋值。为什么?好吧,要么试图取消引用一个尚未分配的变量将是一个错误(在这种情况下你的代码会中断),要么它将评估为某个默认对象,在这种情况下你将不知道它是否评估为那个对象,因为该变量未分配或因为有人将该对象分配给该变量。

在Ruby中,这两种情况都可能发生,具体取决于变量的种类:

UnassignedConstant.nil?
# Boom! NameError

@unassigned_instance_variable.nil?
# => true
# but is it true because it was unassigned or because someone assigned nil?

无论哪种方式,简单的逻辑告诉我们,对变量 调用方法不能 可能回答我们的问题。我们无法通过取消引用我们的变量来确定它是否已分配。我们必须寻找其他方式,寻找一些将变量作为参数的反射方法(更准确地说,它将 变量的名称 作为参数;方法不能采用Ruby 中的变量作为参数,因为变量不是对象,你只能将对象作为参数)。谢天谢地,有很多这样的方法:

[BTW: 注意全局变量没有对应的方法,不知道为什么。]

在你的情况下,你显然想要后者:

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

[请注意,您的代码还有其他问题,例如 query_hash 未定义,但这些不在本问题的范围内。]