<?xml version="1.0" encoding="UTF-8"?>
<article>
  <allow-comments type="boolean">true</allow-comments>
  <cite nil="true"></cite>
  <comment-counter type="integer" nil="true"></comment-counter>
  <content>Pop quiz: your browsing some ruby code (which you often do in your spare time) and see the following:

        party_like[:its] = &quot;1999&quot;
        puts party_like[:its]

What will be put to the console when these lines of ruby execute? You might be saying that since party_like seems to be some kind of Hash or a Hash-like-thingie, you should get...

        #=&gt; 1999

At least 99% of the time you'd be right, unless the code is actually the cookies method in a Rails Controller:

        cookies[:its] = &quot;1999&quot;
        puts cookies[:its]

        #=&gt; nil

BUWAHHHHHH? Cookies isn't a Hash, although the cookies method does return a CookieJar object, which extends Hash. CookieJar mangles the expected Hash methods of [] and []= with these gotchas:

* The CookieJar object does not represent one set of cookies, it represents 2 sets: the incoming cookies from the browser, and the outgoing cookies that will be sent back to the client
* `cookies[:key]`gets you the incoming cookies from the client
* `cookies[:key]=` value sets outgoing cookies that will be sent back to the client
* ... all of which mean that `cookies[:its] = &quot;1999&quot;` will not allow you to retrieve that value with `cookies[:its]`.

But wait, it gets more confusing. In a test you do the following:

        def test_cookies
          @request.cookies[:its] = &quot;1999&quot;
           get :index
        end

And in your controller:

        class CookiesController &lt; ApplicationController
          def index
            puts cookies[:its]           #=&gt; nil
            puts cookies.inspect    #=&gt; {:its=&gt;&quot;1999&quot;}
            render :text =&gt; &quot;&quot;
          end
        end

The cookies.inspect confusingly returns {:its=&gt;&quot;1999&quot;}, which seems impossible: I put the value in and get nil when I ask for it, but if I inspect the object to see what's up, it's there! Right? Not, not really. The incoming cookies are displayed, not the outgoing. In a typical test-fail-debug scenario, this is a head-scratcher.

For the love of SANITY: do not override methods on core objects to do completely unexpected stuff, and especially don't mangle the expected functionality of operators! I realize that with languages like ruby you can play God, overriding and changing the implementation of anything you please, but some things are sacred: +,-, [], []=, etc. + should add stuff. - should remove stuff. And objects that have [] and []= should let you get stuff with [key] and set them with [key]=value.

****
####1 Comments (from old blog):

At 10/13/2006 5:33 PM, Joshua Jarman said&#226;&#8364;&#166;

I have a slightly different take on the cookies object. It is a hash, with a wormhole inside connecting it to the last and next browser requests. Essentially it doesn't exist in the now. ;-)

Cookies are decoupled. When you set the value it starts a chain of events. The server needs to send the cookie to the browser and the browser has to return the cookie. Then you can read the value.

        cookies[:its] = &quot;1999&quot;

        *server response
        *browser request

          p cookies[:its]
          #=&gt; &quot;1999&quot;


You can use &quot;app&quot; in tests (or the console) to simulate user sessions and to send and receive cookies, which will allow you to get your values back out and check them.

Example:&lt;br&gt;
[http://clarkware.com/cgi/blosxom/2006/04/04](http://clarkware.com/cgi/blosxom/2006/04/04)

So maybe more twisted and misunderstood then broken.

Cheers,&lt;br&gt;
Josh</content>
  <created-at type="datetime">2007-01-04T06:55:23-06:00</created-at>
  <deleted-at type="datetime" nil="true"></deleted-at>
  <feed-id type="integer" nil="true"></feed-id>
  <format nil="true"></format>
  <header>Rails Cookies Mangles the Hash Interface</header>
  <id type="integer">18</id>
  <lang nil="true"></lang>
  <permalink>rails-cookies-mangles-the-hash-interface</permalink>
  <updated-at type="datetime">2009-02-18T13:55:45Z</updated-at>
  <user-id type="integer">1</user-id>
</article>
