Constant Hash strangeness

Hello.

This seems to be trivial, yet I can't find an explanation for it
anywhere online. Apologies if I'm asking the obvious.

If you create a constant hash:

     CONSTANTHASH = { :foo => "foobar" }
     x = CONSTANTHASH[:foo]
     x << "-suffix"
     p CONSTANTHASH

One gets the following output:

     { :foo => "foobar-suffix" }
     nil

So, this sort of makes sense if one considers that variables in Ruby
are references. So Ruby only protects the hash, not the values keys in
the hash point to. But... is there any way to protect the values, and
not just the keys?

Thanks.

Warm Regards,

Wiktor Macura

It's not a constant hash, but rather a constant which holds a reference to a hash. The constant can't be changed to point to a different hash (well ... not without a warning anyway), but the hash itself can still be modified:

CONSTANTHASH = { :foo => "foobar" }
CONSTANTHASH[:bar] = "zoom"
p CONSTANTHASH[:bar]

If you want to render an object immune to modification, freeze it.

CONSTANTHASH = { :foo => "foobar".freeze }.freeze

(It isn't necessary to freeze "value types" like symbols or fixnums, though, since -- unlike strings or hashes -- they are naturally immutable.)

-mental

···

On Thu, 1 Jun 2006 04:29:39 +0900, "Wiktor Macura" <wmacura@gmail.com> wrote:

Hello.

This seems to be trivial, yet I can't find an explanation for it
anywhere online. Apologies if I'm asking the obvious.

If you create a constant hash:

     CONSTANTHASH = { :foo => "foobar" }
     x = CONSTANTHASH[:foo]
     x << "-suffix"
     p CONSTANTHASH

Constants don't work the way that you think they do. I'll be posting
an article about this soon; I just haven't decided where to put it.

-austin

···

On 5/31/06, Wiktor Macura <wmacura@gmail.com> wrote:

Hello.

This seems to be trivial, yet I can't find an explanation for it
anywhere online. Apologies if I'm asking the obvious.

If you create a constant hash:

     CONSTANTHASH = { :foo => "foobar" }
     x = CONSTANTHASH[:foo]
     x << "-suffix"
     p CONSTANTHASH

One gets the following output:

     { :foo => "foobar-suffix" }
     nil

So, this sort of makes sense if one considers that variables in Ruby
are references. So Ruby only protects the hash, not the values keys in
the hash point to. But... is there any way to protect the values, and
not just the keys?

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

Hello.

Well, thanks for taking the time to do the article... and if you need
anyone to proof-read/test it. :slight_smile:

Cheers.

Wiktor

···

On 5/31/06, Austin Ziegler <halostatue@gmail.com> wrote:

On 5/31/06, Wiktor Macura <wmacura@gmail.com> wrote:
> Hello.
>
> This seems to be trivial, yet I can't find an explanation for it
> anywhere online. Apologies if I'm asking the obvious.
>
> If you create a constant hash:
>
> CONSTANTHASH = { :foo => "foobar" }
> x = CONSTANTHASH[:foo]
> x << "-suffix"
> p CONSTANTHASH
>
> One gets the following output:
>
> { :foo => "foobar-suffix" }
> nil
>
> So, this sort of makes sense if one considers that variables in Ruby
> are references. So Ruby only protects the hash, not the values keys in
> the hash point to. But... is there any way to protect the values, and
> not just the keys?

Constants don't work the way that you think they do. I'll be posting
an article about this soon; I just haven't decided where to put it.

-austin
--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

Thank you. I was surprised by the way hash behaves, but I do
understand why. Its obvious in hind-sight, I guess you could say. But
thanks for the .freeze example, that's exactly what I was look for.

Many thanks,

Wiktor

···

On 5/31/06, MenTaLguY <mental@rydia.net> wrote:

On Thu, 1 Jun 2006 04:29:39 +0900, "Wiktor Macura" <wmacura@gmail.com> wrote:
> Hello.
>
> This seems to be trivial, yet I can't find an explanation for it
> anywhere online. Apologies if I'm asking the obvious.
>
> If you create a constant hash:
>
> CONSTANTHASH = { :foo => "foobar" }
> x = CONSTANTHASH[:foo]
> x << "-suffix"
> p CONSTANTHASH

It's not a constant hash, but rather a constant which holds a reference to a hash. The constant can't be changed to point to a different hash (well ... not without a warning anyway), but the hash itself can still be modified:

CONSTANTHASH = { :foo => "foobar" }
CONSTANTHASH[:bar] = "zoom"
p CONSTANTHASH[:bar]

If you want to render an object immune to modification, freeze it.

CONSTANTHASH = { :foo => "foobar".freeze }.freeze

(It isn't necessary to freeze "value types" like symbols or fixnums, though, since -- unlike strings or hashes -- they are naturally immutable.)

-mental