After doing a lot of debugging, I have isolated a problem but I cannot explain it. Here is a bit of Sinatra Code:
post '/modify' do
# at this point params contains the action key as I expect it.
puts "1: action is #{params["action"]}"
if (params["action"] == "del")
puts "#{params}"
puts "delete"
end
# At this point params still contains the "action" key as I expect it
puts "2: action is #{params["action"]}"
if (params["action"] == 'create')
puts "#{params}"
puts "create"
#### THE NEXT LINE IS THE PROBLEM!
params = { :n => @number }
redirect '/'
end
# At this point params is nil
puts "3: ????? #{params}"
foo = params["action"]
#puts "3: action is #{params["action"]}"
if (foo == "refresh")
puts "***: #{params}"
redirect '/'
end
puts "3: #{params}"
puts "3: action is #{params["action"]}"
end
This code as written, when params["action"] is not equal to del or create, will give an error that [] is not valid on a nil value.
I conclude that by assigning a value to params inside a conditional that IS NOT EXECUTED the params hash (which is really a method from Sinatra) becomes nil.
Even if there was something with variable scoping in Ruby that doesn't recognize a if/then as a new scope, still that line is not executed.
Can you see it?
You seem to confuse the method params
for the local variable params
.
Let's take a look at a simplified example:
def params
{"action" => "some-action"}
end
# the line below refers to the method #params
p params # {"action" => "some-action"}
# the variable params is created, but not assigned
params = {n: 1} if false
# any further reference to params will use the variable
p params # nil
If you now have the question "why is the variable created?" the simple answer is: Because the documentation says so.
The local variable is created when the parser encounters the assignment, not when the assignment occurs:
a = 0 if false # does not assign to a p local_variables # prints [:a] p a # prints nil
To solve your issue either use the #params=
setter (assuming there is one) or retrieve the method result to a variable to start with, this way all references to params
refer to the variable.
# assign using the setter method
self.params = { :n => @number }
# extract the contents to a variable at the start
# of the `post '/modify' do` block
params = self.params # or params()