Hi,
Getting confused with Hashes a bit. It seems sometimes I can use both a
Symbol or a String to get the value back, but other times the Symbol doesn't
work. Is there any rule re how to remember how Hash handles setting and
getting values uses Symbol / String?
e.g. hash_variable[:amount] versus hash_variable["amount"]
e.g. hash_var = {:amount => 10}, versus hash_var = {"amount" => 10)
In general, a hash uses eql? to know if a key matches the one you are
asking for.
So in general a Symbol and it's String counterpart are not the same
key in a hash.
There are different implementations that allow using Strings / Symbols
to refer to the same key.
Search for HashWithIndifferentAccess or something like that. I think
Rails uses something similar, IIRC.
Maybe your confusing comes from the different behaviour when you are
using Rails vs non-Rails?
Jesus.
···
On Mon, Jan 12, 2009 at 9:50 PM, Greg Hauptmann <greg.hauptmann.ruby@gmail.com> wrote:
Hi,
Getting confused with Hashes a bit. It seems sometimes I can use both a
Symbol or a String to get the value back, but other times the Symbol doesn't
work. Is there any rule re how to remember how Hash handles setting and
getting values uses Symbol / String?
e.g. hash_variable[:amount] versus hash_variable["amount"]
e.g. hash_var = {:amount => 10}, versus hash_var = {"amount" => 10)
Alle lunedì 12 gennaio 2009, Greg Hauptmann ha scritto:
Hi,
Getting confused with Hashes a bit. It seems sometimes I can use both a
Symbol or a String to get the value back, but other times the Symbol
doesn't work. Is there any rule re how to remember how Hash handles
setting and getting values uses Symbol / String?
e.g. hash_variable[:amount] versus hash_variable["amount"]
e.g. hash_var = {:amount => 10}, versus hash_var = {"amount" => 10)
By itself, a hash distinguish between strings and symbols, so if an entry is
stored under a string key, you'll only be able to retrieve it using a string
key. If the entry has a symbol entry, then it can only be obtained using a
symbol key:
You can setup the hash so that it will work either with strings or symbols.
For example:
hash = Hash.new do |h, k|
if k.is_a?(String) and h.has_key? k.to_sym then h[k] = h[k.to_sym]
elsif k.is_a?(Symbol) and h.has_key? k.to_s then h[k] = h[k.to_s]
else nil
end
end
Hi,
Getting confused with Hashes a bit. It seems sometimes I can use both a
Symbol or a String to get the value back, but other times the Symbol doesn't
work. Is there any rule re how to remember how Hash handles setting and
getting values uses Symbol / String?
e.g. hash_variable[:amount] versus hash_variable["amount"]
e.g. hash_var = {:amount => 10}, versus hash_var = {"amount" => 10)
first:
every time you call hash_var["amount"] a new string is created.
But if you call with :amount, :amount will always be the same object.
next:
the default Hash class does not mix String- and Symbol-Keys.
so
hash_var[:amount] = 10
hash_var["amount"] = 11
hash_var[:amount] != hash_var["amount"] # => true
but for example ActiveSupport (used in Rails) defines a class HashWithIndifferentAccess.
there all Symbol-keys gets converted to a String, so that either :amount or "amount" point to the same entry.
So if you want to know how to handle it, ask the variable for its class (if someone uses monkey-patching you will lose =P)
thanks guys - interesting question for the Rails guys is whether you have to
explicitly ask for a HashWithIndifference, i.e. just wondering whether it's
possible in Rails to ask for a Hash but really get a monkey patched
HashWithIndiffrence back without it being obvious...
···
On Tue, Jan 13, 2009 at 7:03 AM, badboy <badboy@heartofgold.co.cc> wrote:
Greg Hauptmann schrieb:
Hi,
Getting confused with Hashes a bit. It seems sometimes I can use both a
Symbol or a String to get the value back, but other times the Symbol
doesn't
work. Is there any rule re how to remember how Hash handles setting and
getting values uses Symbol / String?
e.g. hash_variable[:amount] versus hash_variable["amount"]
e.g. hash_var = {:amount => 10}, versus hash_var = {"amount" => 10)
first:
every time you call hash_var["amount"] a new string is created.
But if you call with :amount, :amount will always be the same object.
next:
the default Hash class does not mix String- and Symbol-Keys.
so
hash_var[:amount] = 10
hash_var["amount"] = 11
hash_var[:amount] != hash_var["amount"] # => true
but for example ActiveSupport (used in Rails) defines a class
HashWithIndifferentAccess.
there all Symbol-keys gets converted to a String, so that either :amount or
"amount" point to the same entry.
So if you want to know how to handle it, ask the variable for its class (if
someone uses monkey-patching you will lose =P)
IMHO there is a downside to assign to the hash in the block because that changes the Hash. This would not work with a frozen Hash for example.
I'd probably rather adjust keys on insertion and retrieval, e.g. always change them to Symbols.
Kind regards
robert
···
On 12.01.2009 22:02, Stefano Crocco wrote:
Alle lunedì 12 gennaio 2009, Greg Hauptmann ha scritto:
Hi,
Getting confused with Hashes a bit. It seems sometimes I can use both a
Symbol or a String to get the value back, but other times the Symbol
doesn't work. Is there any rule re how to remember how Hash handles
setting and getting values uses Symbol / String?
e.g. hash_variable[:amount] versus hash_variable["amount"]
e.g. hash_var = {:amount => 10}, versus hash_var = {"amount" => 10)
By itself, a hash distinguish between strings and symbols, so if an entry is stored under a string key, you'll only be able to retrieve it using a string key. If the entry has a symbol entry, then it can only be obtained using a symbol key:
You can setup the hash so that it will work either with strings or symbols. For example:
hash = Hash.new do |h, k|
if k.is_a?(String) and h.has_key? k.to_sym then h[k] = h[k.to_sym]
elsif k.is_a?(Symbol) and h.has_key? k.to_s then h[k] = h[k.to_s]
else nil
end
end
--
remember.guy do |as, often| as.you_can - without end
thanks guys - interesting question for the Rails guys is whether you have to
explicitly ask for a HashWithIndifference, i.e. just wondering whether it's
possible in Rails to ask for a Hash but really get a monkey patched
HashWithIndiffrence back without it being obvious...
HashWithIndifferentAccess is just a subclass of Hash. I don't think it
can be described as monkey patched, though I'm never sure what that
term means. Some methods return instances of it; some return instances
of Hash.
thanks guys - interesting question for the Rails guys is whether you
have to
explicitly ask for a HashWithIndifference, i.e. just wondering whether
it's
possible in Rails to ask for a Hash but really get a monkey patched
HashWithIndiffrence back without it being obvious...
There is no guarantees of getting any "type" back from ANY method in
ruby.. with rails, you can just convert it to an one if you aren't
sure..
my_hash = HashWithIndifferentAccess.new(my_hash)
By the way, there is no monkey patching here.. HashWithIndifferentAccess
is it's own class. To be considered monkey patching, the Hash class
itself would be modified to be used in an indifferent fashion..
agreed - slip on my part to use the term - what I meant to refer to was
"Some methods return instances of it; some return instances of Hash" - as
Ilan pointed out, confirming that Rails can do this to you...
···
On Tue, Jan 13, 2009 at 7:35 AM, Ilan Berci <coder68@yahoo.com> wrote:
Greg Hauptmann wrote:
> thanks guys - interesting question for the Rails guys is whether you
> have to
> explicitly ask for a HashWithIndifference, i.e. just wondering whether
> it's
> possible in Rails to ask for a Hash but really get a monkey patched
> HashWithIndiffrence back without it being obvious...
There is no guarantees of getting any "type" back from ANY method in
ruby.. with rails, you can just convert it to an one if you aren't
sure..
my_hash = HashWithIndifferentAccess.new(my_hash)
By the way, there is no monkey patching here.. HashWithIndifferentAccess
is it's own class. To be considered monkey patching, the Hash class
itself would be modified to be used in an indifferent fashion..