Announcement (2017-05-07): www.ruby-forum.com is now read-only since I
unfortunately do not have the time to support and maintain the forum any
more. Please see rubyonrails.org/community and ruby-lang.org/en/community
for other Rails- und Ruby-related community platforms.

Hi all.
Let's say I want to either create a new named array or append to that
array if it already exists. Is there a more elegant way of doing the
following?
>> @foo[:bar].nil? ? foo[:bar] = ["snafu"] : foo[:bar] << "snafu"
Thanks!
/afb

Adam Block wrote:
> Hi all.>> Let's say I want to either create a new named array or append to that> array if it already exists. Is there a more elegant way of doing the> following?>>>> @foo[:bar].nil? ? foo[:bar] = ["snafu"] : foo[:bar] << "snafu"
I would use:
@foo[:bar] ||= []
@foo[:bar] << "snafu"
There probably is more compact, but I find this writing very readable
when you're used to it (though, admittedly somehow puzzling for the
beginners).
Cheers,
Vince

Adam Block wrote:
> Let's say I want to either create a new named array or append to that> array if it already exists. Is there a more elegant way of doing the> following?>> >> @foo[:bar].nil? ? foo[:bar] = ["snafu"] : foo[:bar] << "snafu"
Dunno if you'd call it elegant, but I frequently write:
( @foo[:bar] ||= [] ) << "snafu"

On 20.01.2007 18:55, Adam Block wrote:
> Hi all.>> Let's say I want to either create a new named array or append to that> array if it already exists. Is there a more elegant way of doing the> following?>>>> @foo[:bar].nil? ? foo[:bar] = ["snafu"] : foo[:bar] << "snafu"
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
def other_method
...
@foo[:bar] << "snafu"
...
end
Kind regards
robert

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.

On Jan 20, 2007, at 1:15 PM, Phrogz wrote:
> 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:
>> myhash = Hash.new { |h,k| h[k] = Array.new }
=> {}
>> if myhash[:oops]
>> puts "nothing"
>> end
nothing
=> nil
>> myhash
=> {:oops=>[]}
>> if myhash.has_key? :missing
>> puts ":missing contains #{myhash[:missing] * ', '}"
>> end
=> nil
>> myhash
=> {:oops=>[]}
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.
-Rob
Rob Biedenharn http://agileconsultingllc.com
Rob@AgileConsultingLLC.com

Phrogz wrote:
> 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
}
--- output -----
22^yes
33
bar