如何在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 中的变量作为参数,因为变量不是对象,你只能将对象作为参数)。谢天谢地,有很多这样的方法:
Module#const_defined?
Module#class_variable_defined?
Binding#local_variable_defined?
Object#instance_variable_defined?
[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
未定义,但这些不在本问题的范围内。]
我有以下 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 中的变量作为参数,因为变量不是对象,你只能将对象作为参数)。谢天谢地,有很多这样的方法:
Module#const_defined?
Module#class_variable_defined?
Binding#local_variable_defined?
Object#instance_variable_defined?
[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
未定义,但这些不在本问题的范围内。]