> Hi,
>
>
> >This suggests me that the keys are actually stored in the hash by
> >reference, not by value as I would expect from my prior experience
> >with other languages.
>
> Hash stores its values, as its name suggests, by hash values from
> keys. So, if you modifies the key, and subsequently the hash value of
> the key, it screws up. As a general rule, don't modify the keys, or
> if you really need to modify the key for some unknown reason, call
> rehash method on the hash.
So the real answer to my question (what is the reason for hash to
store it's keys by reference?) might be: trading rule of a thumb for
speed and memory?
No, the reason is that you can only store by reference in Ruby (there
are some internal optimizations for Fixnum and the like but the code
still basically behaves the same).
If no one is ever going to modify the hash key,
there is no reason to copy it...
There is also the issue that a key's hash value will likely change if
you change a Hash key. So it is *never* a good idea to modify a Hash
key. Note though that there is an exception: Strings are cloned if
they are not frozen to avoid nasty effects.
OK, I think I got it.
If someone wonder how could I come up with modifying the hash keys:
this is my second program in Ruby and was coding a Ruby version of a
speech generator example from the Pike & Kernigan's "Practical
programming". Here is the code snippet:
state={}
prefix=
while $stdin.eof?
Are you serious about the line above? I'd rather have expected "until" there.
I'd do this, note all the freezing in order to make errors with
changing keys obvious.
state = Hash.new {|h,k| h[k]=}
prefix = .freeze
ARGF.each do |line|
line.scan /\w+/ do |word|
state[prefix] << word.freeze
(prefix += [word]).freeze
# or: prefix = (prefix.dup << word).freeze
end
end
Btw, there's probably a more efficient way of storing this if you
introduce a specialized class for prefix chaining. Probably like
this:
Prefix = Struct.new :word, :previous
w=... # read a word
state[prefix] << w
...
prefix << w # <-- Bang! The hash key is changed...
You can #dup the prefix or use +:
prefix += [w]
Kind regards
robert
This will implicitly create a new Array.
Kind regards
robert
路路路
2007/9/17, Alex Shulgin <alex.shulgin@gmail.com>:
On Sep 17, 3:42 am, Yukihiro Matsumoto <m...@ruby-lang.org> wrote:
> In message "Re: Modifying a hash key" > > on Sun, 16 Sep 2007 17:10:05 +0900, Alex Shulgin <alex.shul...@gmail.com> writes: