为什么在html.erb中未声明的@variables为nil而不是NameError

时间:2014-08-08 05:18:53

标签: ruby-on-rails ruby erb

如果 html.erb 文件在控制器中分配了而没有变量(例如@user = params["user_name"] ),那么为什么它会将@user视为{ {1}}而不是抛出nil

例如:

NameError: undefined local variable

如果控制器将问候语传递给<%= render partial: "greeting", locals: { user: @user } if @user %> ,这将呈现问候语,但如果页面是第一次呈现且用户尚未输入其用户名,则问候语根本就不存在,而不是导致错误。在我看来,@user永远不会在 html.erb 执行的本地范围内声明,因此它应该导致错误。

这里发生了什么?也许@user以某种方式预处理意味着将变量视为符号并将其用作@哈希中的键并返回结果?

2 个答案:

答案 0 :(得分:5)

未初始化的实例变量(@...)评估为nil。您仍然可以使用nil方法检查是否已分配实例变量(包括分配到defined?):

[1] pry(main)> defined? @test
=> nil
[2] pry(main)> @test = nil
=> nil
[3] pry(main)> defined? @test
=> "instance-variable"

答案 1 :(得分:0)

  

那么为什么它会将@user视为nil而不是投放NameError: undefined local variable

嗯,它不是一个局部变量,它是一个实例变量。

但即使局部变量的行为方式也相同:

if false
  local_var = 42 # needed so Ruby knows `local_var` isn't a method call
end

local_var
# => nil

@instance_variable
# => nil

$global_variable
# => nil

但奇怪的是:

Constant
# NameError: uninitialized constant Constant

@@class_variable
# NameError: uninitialized class variable @@class_variable in Object