Reputation: 7384
In debugging console, while app running (using binding.pry to interrupt it), I can see that my variable Rails.configuration.hardcoded_current_user_key
is set:
pry(#<TasksController>)> Rails.configuration.hardcoded_current_user_key
=> "dev"
But it doesn't appear to be defined:
pry(#<TasksController>)> defined?(Rails.configuration.hardcoded_current_user_key)
=> nil
Yet it works fine to store and test its value:
pry(#<TasksController>)> tempVar = Rails.configuration.hardcoded_current_user_key
=> "dev"
pry(#<TasksController>)> defined?(tempVar)
=> "local-variable"
What is going on?
Upvotes: 3
Views: 154
Reputation: 15945
This is because Rails config implements respond_to?
but not respond_to_missing?
, and defined?
only recognizes respond_to_missing?
:
class X
def respond_to?(name, include_all = false)
name == :another_secret || super
end
private
def method_missing(name, *args, &block)
case name
when :super_secret
'Bingo!'
when :another_secret
'Nope.'
else
super
end
end
def respond_to_missing?(name, include_all = false)
name == :super_secret || super
end
end
x = X.new
puts x.super_secret # => Bingo!
p defined?(x.super_secret) # => "method"
puts x.another_secret # => Nope.
p defined?(x.another_secret) # => nil
It's recommended to implement respond_to_missing?
along with method_missing
, I too wonder why Rails did it that way.
Upvotes: 4
Reputation: 211740
You shouldn't be using defined?
on anything but the "stub" of that, or in other words, merely this:
defined?(Rails)
Anything beyond that is highly unusual to see, and I'm not even sure it's valid.
defined?
is not a method, but a construct that tests if the following thing is defined as a variable, constant or method, among other things. It won't evaluate your code, it will just test it as-is. This means method calls don't happen, and as such, can't be chained.
If you want to test that something is assigned, then you should use this:
Rails.configuration.hardcoded_current_user_key.nil?
Upvotes: 0