monsterooo / blog

and make promises by the hours
MIT License
14 stars 1 forks source link

如何检查变量是否在ruby中定义 #29

Open monsterooo opened 5 years ago

monsterooo commented 5 years ago

在ruby中有defined?关键字帮助您检测一个变量是否定义

如果变量存在您将获得它的类型

apple = 1
p defined?(apple)
# => "local-variable"

如果变量没有定义您将获得nil

defined?(yoho) # => nil

这个 defined? 有点类似 javascript 的 typeof 运算符,但是如果你想知道对象的类型可以在对象上使用 class 方法

一些有意思的注意点:

检查变量定义更好的方法

这个关键字很有用,但它存在一些问题。为什么?

因为其运算符优先级很低。

如果您像下面这样做:

defined? apple && apple.size

上面代码返回的结果是这个表达式的结果

因为 apple && apple.size 被解释为了 defined? 的参数

正确的做法应该是:

defined?(apple) && apple.size

ruby还有其他方法检查变量是否定义

local variables

local_variables.include?(:apple)

instance variables

instance_variable_defined?("@food")

但您可能不会使用这些

在99%的情况下,如果没有申明本地变量您会得到一个拼写错误

关于实例变量

未定义的实例变量总是为 nil,所以你需要检查它

可以尝试一下"安全导航操作符"(Ruby 2.3+) ,如果变量不是 nil 会调用这个方法

下面是一个例子:

if @user&.country == "Spain"
  # ...
end

上面的代码相当于:

if @user && @user.country == "Spain"
  # ...
end

"安全导航操作符"不像 defined? 那样普遍,但是它更容易预测更不容易出错

检查一个方法是否定义

您可以使用 defined? 检查方法是否定义。但它不是最佳实践

举个例子:

defined?(puts)
# "method"

因为 defined? 是一个关键字而不是方法,所以不能与对象一起使用

我是这个意思:

[].defined?(:size)
# undefined method `defined?' for []:Array

如何达到和类一起使用呢,像下面这样:

[].respond_to?(:size)
# true
[].respond_to?(:orange)
# false

检查一个类是否存在

举个例子:

defined?(Object)
# "constant"
defined?(A)
# nil

上面代码更好的方式是使用 const_defined? 方法。代码如下:

Object.const_defined?(:String)
# true
Object.const_defined?(:A)
# false

本章完啦。感谢阅读🙏