Two Questions about Hash Defaults

P

Pete Elmore

I have a couple of questions about hashes. The first is fairly simple:
is there a way to set a default so that when the value for a key is
changed, the object it points to is default.dup instead of default? So
that if I do something like this:

lists = Hash.new([])
lists[:a].push 1
lists[:b].push 2
# Then doing the following
p lists[:a]
# Gets me
=> [1]
# Instead of
=> [1, 2]

And 'lists' is '{:a => [1], :b => [2]}' instead of '{}' with a default
of '[1, 2]'.

I know why it happens this way, but is it possible to get it to behave
differently? So that instead of
lists[key] = [] if lists[key].nil? # Assuming default is nil
lists[key].push value
or
lists[key] = lists[key].dup.push value # default is []
I can write simply
lists[key].push value # default is []

The second question is about setting defaults from one hash based on
another. This question is more along the lines of 'Does this code
violate Ruby sensibilities?'

class Hash
def add_defaults(default_hash)
raise TypeError unless default_hash.kind_of? Hash
default_hash.each { |k,v|
self[k] = v unless self.has_key? k
}
self
end
end

def some_function(str, options=Hash.new(nil))
# Set the defaults
defaults = {
:preserve_breaks => true,
:indent => 0,
:columns => 79,
}
options.add_defaults defaults
end

some_function("asdf", { :preserve_breaks => false })
 
Y

Yukihiro Matsumoto

Hi,

In message "Re: Two Questions about Hash Defaults"
|
|I have a couple of questions about hashes. The first is fairly simple:
|is there a way to set a default so that when the value for a key is
|changed, the object it points to is default.dup instead of default?

list = Hash.new{[]}

|The second question is about setting defaults from one hash based on
|another. This question is more along the lines of 'Does this code
|violate Ruby sensibilities?'

defaults = {
:preserve_breaks => true,
:indent => 0,
:columns => 79,
}
list = Hash.new{|h,k|defaults[k]}
 
S

Saynatkari

Con fecha 2/4/2005 said:
I have a couple of questions about hashes. The first is fairly simple:
is there a way to set a default so that when the value for a key is
changed, the object it points to is default.dup instead of default? So
that if I do something like this:

lists = Hash.new([])
lists[:a].push 1
lists[:b].push 2
# Then doing the following
p lists[:a]
# Gets me
=> [1]
# Instead of
=> [1, 2]

And 'lists' is '{:a => [1], :b => [2]}' instead of '{}' with a default
of '[1, 2]'.

I know why it happens this way, but is it possible to get it to behave
differently? So that instead of
lists[key] = [] if lists[key].nil? # Assuming default is nil
lists[key].push value
or
lists[key] = lists[key].dup.push value # default is []
I can write simply
lists[key].push value # default is []

The second question is about setting defaults from one hash based on
another. This question is more along the lines of 'Does this code
violate Ruby sensibilities?'

class Hash
def add_defaults(default_hash)
raise TypeError unless default_hash.kind_of? Hash
default_hash.each { |k,v|
self[k] = v unless self.has_key? k
}
self
end
end

def some_function(str, options=Hash.new(nil))
# Set the defaults
defaults = {
:preserve_breaks => true,
:indent => 0,
:columns => 79,
}
options.add_defaults defaults
end

some_function("asdf", { :preserve_breaks => false })

Looks like matz already provided you with a good answer,
but here's a different take since I am not sure if you
are indeed referring to default values as the language
defines them or 'just' default values for your application
logic:

def some_function(str, options = {})
defaults = {:preserve => true, :indent => 0, :columns =>79}
options = defaults.merge options
end
 
R

Robert Klemme

Pete Elmore said:
I have a couple of questions about hashes. The first is fairly simple: is
there a way to set a default so that when the value for a key is changed,
the object it points to is default.dup instead of default? So that if I do
something like this:

lists = Hash.new([])

You want this:

lists = Hash.new {|h,k| h[k]=[]}
lists[:a].push 1
lists[:b].push 2
# Then doing the following
p lists[:a]
# Gets me
=> [1]
# Instead of
=> [1, 2]

And 'lists' is '{:a => [1], :b => [2]}' instead of '{}' with a default of
'[1, 2]'.

I know why it happens this way, but is it possible to get it to behave
differently? So that instead of
lists[key] = [] if lists[key].nil? # Assuming default is nil
lists[key].push value
or
lists[key] = lists[key].dup.push value # default is []
I can write simply
lists[key].push value # default is []

The second question is about setting defaults from one hash based on
another. This question is more along the lines of 'Does this code violate
Ruby sensibilities?'

class Hash
def add_defaults(default_hash)
raise TypeError unless default_hash.kind_of? Hash
default_hash.each { |k,v|
self[k] = v unless self.has_key? k
}
self
end
end

def some_function(str, options=Hash.new(nil))
# Set the defaults
defaults = {
:preserve_breaks => true,
:indent => 0,
:columns => 79,
}
options.add_defaults defaults

This should do:
options = defaults.update options
end

some_function("asdf", { :preserve_breaks => false })

Kind regards

robert
 
P

Pete Elmore

Yukihiro said:
Hi, Wow, Matz himself! :)
list = Hash.new{[]}
defaults = {
:preserve_breaks => true,
:indent => 0,
:columns => 79,
}
list = Hash.new{|h,k|defaults[k]}
This is interesting; thanks for the response!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top