Since you're using a Hash the block constructor is the most elegant
solution IMHO:
def initialize @foo = Hash.new {|h,k| h[k]=}
...
end
To be clear for those unfamiliar with this: any time you ask for the
value of a key that doesn't exist, the block will be called (which
creates a new empty array). This means you can never see this
particular Hash has a key, since:
if @foo[ :bar ]
will always succeed, and create a (possibly unwanted) array instance in
the process.
Since you're using a Hash the block constructor is the most elegant
solution IMHO:
def initialize @foo = Hash.new {|h,k| h[k]=}
...
end
To be clear for those unfamiliar with this: any time you ask for the
value of a key that doesn't exist, the block will be called (which
creates a new empty array). This means you can never see this
particular Hash has a key, since:
if @foo[ :bar ]
will always succeed, and create a (possibly unwanted) array instance in
the process.
That's only because you're not checking for the presence of a key correctly:
If you know that your code isn't using the block initialization, then the first form might be OK. However, the #has_key? will always do what you expect. This is particularly true if the value can be nil or false.
Robert Klemme wrote:
> Since you're using a Hash the block constructor is the most elegant
> solution IMHO:
>
> def initialize
> @foo = Hash.new {|h,k| h[k]=}
> ...
> end
To be clear for those unfamiliar with this: any time you ask for the
value of a key that doesn't exist, the block will be called (which
creates a new empty array). This means you can never see this
particular Hash has a key, since:
if @foo[ :bar ]
will always succeed, and create a (possibly unwanted) array instance in
the process.
What if foo[:bar] has been assigned a value of false?
That method of checking for the presence of a key is
too crude even for awk. Note below that the mere
attempt to access the value of a key creates an
entry for that key if it doesn't already exist.
BEGIN {
SUBSEP = "^"
a[22,"yes"] = 88
a[33] = 99
# The wrong way.
if ( a["bar"] )
print "How did 'bar' get here?"
# The right way.
if ( "foo" in a )
print "'foo' too?"
# Any unauthorized entries?
for (key in a)
print key
}
> Robert Klemme wrote:
>> Since you're using a Hash the block constructor is the most elegant
>> solution IMHO:
>>
>> def initialize
>> @foo = Hash.new {|h,k| h[k]=}
>> ...
>> end
>
> To be clear for those unfamiliar with this: any time you ask for the
> value of a key that doesn't exist, the block will be called (which
> creates a new empty array). This means you can never see this
> particular Hash has a key, since:
> if @foo[ :bar ]
> will always succeed, and create a (possibly unwanted) array
> instance in
> the process.
That's only because you're not checking for the presence of a key
correctly: