Ruby enhancement suggestion

I’m fairly certain this isn’t the proper place to suggestion minor
improvements/extensions to the ruby language, but this is something I
constantly find myself wishing was available:

Extension to ruby class Hash

class Hash
def join(key_value_sep="=>", pair_sep=",")
result = “”
self.each { |k,v| result << k.to_s << key_value_sep << v.to_s <<
pair_sep }
result.chomp pair_sep
end
end

I’m sure there’s an even cleaner way to do this (and I’d love to see
it!!), but the point is so that I can do something like this:

hash = {}
=> {}

(0…20).each {|i| hash[i] = i+1 }
=> 0…20

hash.join
=>
“16=>17,5=>6,11=>12,0=>1,17=>18,6=>7,12=>13,1=>2,18=>19,7=>8,13=>14,2=>3,19=>20,8=>9,14=>15,3=>4,20=>21,9=>10,15=>16,4=>5,10=>11”

hash.join " maps to ", ", "
=> “16 maps to 17, 5 maps to 6, 11 maps to 12, 0 maps to 1, 17 maps to
18, 6 maps to 7, 12 maps to 13, 1 maps to 2, 18 maps to 19, 7 maps to 8,
13 maps to 14, 2 maps to 3, 19 maps to 20, 8 maps to 9, 14 maps to 15, 3
maps to 4, 20 maps to 21, 9 maps to 10, 15 maps to 16, 4 maps to 5, 10
maps to 11”

Is there currently some easy, builtin way to get this sort of output
that I’m simply unaware of??

Steve H. wrote:

class Hash
def join(key_value_sep="=>", pair_sep=",")
result = “”
self.each { |k,v| result << k.to_s << key_value_sep << v.to_s <<
pair_sep }
result.chomp pair_sep
end
end

Not too hard in ruby:

h = {:a => 1, :b => 2, :c => 3}

p h.map{|pair| pair.join("=>")}.join(",")

That’s short enough that I wouldn’t bother with a method, but if you
prefer:

class Hash
def join(key_value_sep="=>", pair_sep=",")
map{|pair| pair.join(key_value_sep)}.join(pair_sep)
end
end

I guess the reason this isn’t standard is that it is not very common (?)
to treat the keys and values of a hash as strings, regardless of what
they really are (note that the fact that keys are symbols is lost in the
code above).

Extension to ruby class Hash

it!!), but the point is so that I can do something like this:
=> “16 maps to 17, 5 maps to 6, 11 maps to 12, 0 maps to 1, 17 maps to
18, 6 maps to 7, 12 maps to 13, 1 maps to 2, 18 maps to 19, 7 maps to
8,
13 maps to 14, 2 maps to 3, 19 maps to 20, 8 maps to 9, 14 maps to 15,
3
maps to 4, 20 maps to 21, 9 maps to 10, 15 maps to 16, 4 maps to 5, 10
maps to 11”

Is there currently some easy, builtin way to get this sort of output
that I’m simply unaware of??

Pretty print might suit your needs.

require ‘pp’

pp hash

Regards,

Dan

Joel VanderWerf wrote:

p h.map{|pair| pair.join("=>")}.join(",")

That is indeed nice and compact. Thanks Joel!! That’ll do quite nicely
for my needs. :slight_smile:

Daniel B. wrote:

require ‘pp’
pp hash

Thanks Dan! That’s a cool feature, but not really what I’m looking for
in the hash.join idea. It is indeed something I’ll be using in the
future though. :slight_smile:

On Jun 1, 2009, at 10:01 PM, Steve H. wrote:

Thanks Dan! That’s a cool feature, but not really what I’m looking
for
in the hash.join idea. It is indeed something I’ll be using in the
future though. :slight_smile:

Before the other replies, I was thinking that you just wanted
Hash#inspect

irb> hash = {}
=> {}
irb> (0…20).each {|i| hash[i] = i+1 }
=> 0…20
irb> hash
=> {16=>17, 5=>6, 11=>12, 0=>1, 17=>18, 6=>7, 12=>13, 1=>2, 18=>19,
7=>8, 13=>14, 2=>3, 19=>20, 8=>9, 14=>15, 3=>4, 20=>21, 9=>10, 15=>16,
4=>5, 10=>11}
irb> puts hash.inspect
{16=>17, 5=>6, 11=>12, 0=>1, 17=>18, 6=>7, 12=>13, 1=>2, 18=>19, 7=>8,
13=>14, 2=>3, 19=>20, 8=>9, 14=>15, 3=>4, 20=>21, 9=>10, 15=>16, 4=>5,
10=>11}
=> nil
irb> hash.inspect
=> “{16=>17, 5=>6, 11=>12, 0=>1, 17=>18, 6=>7, 12=>13, 1=>2, 18=>19,
7=>8, 13=>14, 2=>3, 19=>20, 8=>9, 14=>15, 3=>4, 20=>21, 9=>10, 15=>16,
4=>5, 10=>11}”

It even keeps the type of the key straight for you.

irb> {:sym => “I’m a symbol”, ‘string’ => “String here!”, 1 =>
‘Fixnum, too’}.inspect
=> “{1=>"Fixnum, too", :sym=>"I’m a symbol", "string"=>"String
here!"}”

Of course, you could manage that yourself, too, easily enough with
something close to what Joel said:

irb> class Hash
irb> def join(key_value_sep=“=>”, pair_sep=“,”)
irb> map{|k,v|
[k.inspect,v.inspect].join(key_value_sep)}.join(pair_sep)
irb> end
irb> end
=> nil
irb> puts hash.join(" says ", ",\n ")
16 says 17,
5 says 6,
11 says 12,
0 says 1,
17 says 18,
6 says 7,
12 says 13,
1 says 2,
18 says 19,
7 says 8,
13 says 14,
2 says 3,
19 says 20,
8 says 9,
14 says 15,
3 says 4,
20 says 21,
9 says 10,
15 says 16,
4 says 5,
10 says 11
=> nil

Note that #inspect is “smarter” because the individual keys and values
can do what is right for them. Try the simple #join varieties with
values that are themselves Hashes or Arrays.

-Rob

Rob B. http://agileconsultingllc.com
[email protected]