Why undeclared @variables nil in html.erb and not NameError
If the html.erb file is rendered with no variables assigned in the controller (for example, @user = params["user_name"] )
why is it treating @user
like nil
throwing a NameError: undefined local variable
.
Example:
<%= render partial: "greeting", locals: { user: @user } if @user %>
This will give a greeting if the controller passes to it @user
, but if the page is displayed for the first time and the user hasn't entered their username yet, the greeting simply won't be there, instead of causing an error. It seems to me that it @user
will never be declared in the local scope of the html.erb , so it should throw an error.
What's going on here? Perhaps @
somehow preprocessed to mean treating the variable as a character and using it as a key in a hash params
and returning the result?
source to share
Uninitialized instance variables ( @...
) are evaluated before nil
. You can still check if an instance variable (including assignment nil
) has been assigned with the method defined?
:
[1] pry(main)> defined? @test
=> nil
[2] pry(main)> @test = nil
=> nil
[3] pry(main)> defined? @test
=> "instance-variable"
source to share
then why is he considering
@user
hownil
instead of throwingNameError: undefined local variable
.
Well this is not a local variable, it is an instance variable.
But even local variables behave the same:
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
But strange:
Constant
# NameError: uninitialized constant Constant
@@class_variable
# NameError: uninitialized class variable @@class_variable in Object
source to share