In chapter 7 I'm getting the following output with
Interesting question! I searched all library sources of a rails project for
'hash-with-ivars' and only a single place came up: the
psych ruby library for (de-)serializing arbitrary objects to and from YAML. Specifically, these are links to the source code for reading and writing this YAML structure.
In Chapter 7 of the Rails Tutorial, this output comes out as the output of the
debug(params) command that you are instructed to put in a template. The
debug command apparently calls the
psych library to show a readable representation of the object (
params in this case).
params - the universal Rails data structure to hold parameters passed from URLs or forms - is an object that behaves like a
Hash but is not pure hash: it is an instance of class
ActionController::Parameters which is a subclass of
Hash, let's see the class definition:
module ActionController # ... class Parameters < ActiveSupport::HashWithIndifferentAccess # ... end end
HashWithIndifferentAccess is a direct subclass of
As a subclass of
params object can hold other data besides the hash itself and this is what
psych actually supports when trying to print the object in a readable form. Besides printing all the hash elements (under the
elements key), it tries to also list all instance variables of the object and prints it under the
So, all in all, this debug print simply says that the object debugged is an instance of the
ActionController::Parameters class, which is a subclass of
Hash, that besides it's hash elements has also a
@permitted instance variable defined and it is currently set to
false. The two elements, by the way, the
action are parameters used internally by Rails for routing.
When you look into the source of the class again, you will indeed find the
@permitted variable right in the constructor:
class Parameters < ActiveSupport::HashWithIndifferentAccess # ... def initialize(attributes = nil) super(attributes) @permitted = self.class.permit_all_parameters end end
Finally, from the documentation we can conclude that the
@permitted variable holds the state of the params permission. I.e. it is set to
true after the params are permitted by using the
permitted = params.require(:person).permit(:name, :age) permitted.permitted? # this prints out the @permitted instance variable # => true
Update: why the RailsTutorial's debug output differs
The debug output at the RailsTutorial differs a bit - it does not print
ivars. Why? It is because the feature for serializing
hash-with-ivars was added to the
psych gem in its version 2.0.9. The
psych gem is now a part of the Ruby standard library and this particular version of it has been added to the stdlib 2.3.0 preview1 version.
So, the mysteriously different output has a simple explanation: the RailsTutorial author most probably used ruby 2.2 or earlier when writing the book and this ruby version did not display instance variables in the
Hash debug output yet. Actually, there are hints in the tutorial that suggest that the author used ruby 2.1.5.