Define a hash using %q?

Is there a way for us lazy typists to define a hash using %q? I tried
this, but it doesn’t create a hash:

h = %q(a => b, c => d)

Thanks,
Joe

On 10/28/06, Joe R. MUDCRAP-CE [email protected] wrote:

Is there a way for us lazy typists to define a hash using %q? I tried
this, but it doesn’t create a hash:

h = %q(a => b, c => d)

h = {:a => b, :c => d}
h = {‘a’ => b, ‘c’ => d}

Joe R. MUDCRAP-CE wrote:

Is there a way for us lazy typists to define a hash using %q? I tried
this, but it doesn’t create a hash:

h = %q(a => b, c => d)

irb(main):006:0> Hash[*%w{ a b c d }]
=> {“a”=>“b”, “c”=>“d”}

More decadent:

irb(main):008:0> def mkh arg; Hash[*arg]; end
=> nil
irb(main):009:0> mkh %w{ a b c d }
=> {“a”=>“b”, “c”=>“d”}

Ultra decadent:

irb(main):017:0> class Array; def -@; Hash[*self]; end; end
=> nil
irb(main):018:0> -%w{ a b c d }
=> {“a”=>“b”, “c”=>“d”}

Hehe, never mind, no I don’t know how to do that…

Logan C. wrote:

Alternative decandence:
class Array
def to_hsh
require ‘enumerator’
to_enum(:each_slice, 2).to_a.inject({}) { |h, (k, v)| h.update(k=>v) }

Injecting hash may be your idea of decadence, but it’s too much hard
work for me. I just splat myself:

 def to_hsh
   Hash[*self]

On Sun, Oct 29, 2006 at 02:35:02PM +0900, Joel VanderWerf wrote:

=> {“a”=>“b”, “c”=>“d”}

Alternative decandence:

class Array
def to_hsh
require ‘enumerator’
to_enum(:each_slice, 2).to_a.inject({}) { |h, (k, v)| h.update(k=>v)
}
end
end

%w( a b c d ).to_hsh

Logan C. wrote:

Alternative decandence:

class Array
def to_hsh
require ‘enumerator’
to_enum(:each_slice, 2).to_a.inject({}) { |h, (k, v)| h.update(k=>v) }
end
end

%w( a b c d ).to_hsh

Logan, I love you! Just the kind of example I’ve been looking for
–another potential use for a #to_h.

See: RCR 348: Hash#to_h.

T.

Logan C. wrote:

Alternative decandence:

class Array
def to_hsh
require ‘enumerator’
to_enum(:each_slice, 2).to_a.inject({}) { |h, (k, v)| h.update(k=>v) }
end
end

This seems a bit inefficient. If you write a method then I’d prefer

require ‘enumerator’
module Enumerable
def to_hash
h = {}
to_enum(:each_slice, 2).each {|k,v| h[k]=v}
h
end
end

irb(main):021:0> %w( a b c d ).to_hash
=> {“a”=>“b”, “c”=>“d”}
irb(main):022:0> (1…10).to_hash
=> {5=>6, 1=>2, 7=>8, 3=>4, 9=>10}

Kind regards

robert

Robert K. wrote:

irb(main):021:0> %w( a b c d ).to_hash
=> {“a”=>“b”, “c”=>“d”}
irb(main):022:0> (1…10).to_hash
=> {5=>6, 1=>2, 7=>8, 3=>4, 9=>10}

Well, if Ruby had clean blocks, the method using #inject might be more
efficient - I don’t know how expensive the implicit hash construction
for method parameters is. Smalltalk muscle memory working there?

David V.

On Sun, Oct 29, 2006 at 03:56:34PM +0900, Joel VanderWerf wrote:

def to_hsh
  Hash[*self]

See when I usually write this code it’s because it’s coming out of a
#zip, and then you must flatten it to use the splat, and flatten is too
greedy if you nested arrays. So it was force of habit. In this case you
are absolutely correct.

On 10/29/06, Joel VanderWerf [email protected] wrote:

Ultra decadent:

irb(main):017:0> class Array; def -@; Hash[*self]; end; end
=> nil
irb(main):018:0> -%w{ a b c d }
=> {“a”=>“b”, “c”=>“d”}

Nice, but one little edit:

%s/decadent/obfuscated/g

Still neat though.

David V. wrote:

end

irb(main):021:0> %w( a b c d ).to_hash
=> {“a”=>“b”, “c”=>“d”}
irb(main):022:0> (1…10).to_hash
=> {5=>6, 1=>2, 7=>8, 3=>4, 9=>10}

Well, if Ruby had clean blocks, the method using #inject might be more
efficient - I don’t know how expensive the implicit hash construction
for method parameters is. Smalltalk muscle memory working there?

I am not sure what you are at here. Object creation always costs - even
small hashes. Reason is memory allocation and GC management
overhead.

Regards

robert

On 30.10.2006 01:02, David V. wrote:

use a non-closure lambda (cheaper to construct, cacheable). A
smalltalker nerve twitch might make you want to use inject to optimize
this way - using idempotent lambdas where possible.

Ah, thanks for the explanation! Only remark: the block for #inject
would rather look like this, wouldn’t it?

{|h, (k, v)| h[k] = v; h }

Kind regards

robert

On 10/29/06, Robert K. [email protected] wrote:

This seems a bit inefficient. If you write a method then I’d prefer

require ‘enumerator’
module Enumerable
def to_hash
h = {}
to_enum(:each_slice, 2).each {|k,v| h[k]=v}
h
end
end

Never thought I’d see you speak out against inject :slight_smile:

martin

On 30.10.2006 11:03, Martin DeMello wrote:

end
end

Never thought I’d see you speak out against inject :slight_smile:

Yeah, I must have been out of my mind. :slight_smile: I mean, the obvious remedy is
this:

require ‘enumerator’
module Enumerable
def to_hash
to_enum(:each_slice, 2).inject({}) {|h, (k,v)| h[k]=v; h}
end
end

My main point in the other posting was to save the overhead of #to_a and
all the little two element Hashes. With regard to /that/ both variants
are equivalent. But, yes, you’re right of course: I should have posted
the #inject variant right away. I apologize.

:slight_smile:

Kind regards

robert

Robert K. wrote:

Well, if Ruby had clean blocks, the method using #inject might be more
efficient - I don’t know how expensive the implicit hash construction
for method parameters is. Smalltalk muscle memory working there?

I am not sure what you are at here. Object creation always costs - even
small hashes. Reason is memory allocation and GC management overhead.

I meant that with clean blocks, to_enum(:each_slice, 2).to_a.inject({})
{ |h, (k, v)| h[k] = v) } might be the fastest variant because you could
use a non-closure lambda (cheaper to construct, cacheable). A
smalltalker nerve twitch might make you want to use inject to optimize
this way - using idempotent lambdas where possible.

David V.