Define a hash using %q?

  • Thread starter Joe Ruby MUDCRAP-CE
  • Start date
J

Joe Ruby MUDCRAP-CE

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
 
S

snacktime

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}
 
J

Joel VanderWerf

Joe said:
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"}
 
L

Logan Capaldo

Joe said:
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"}
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
 
J

Joel VanderWerf

Logan Capaldo 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]
 
T

Trans

Logan said:
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: http://rcrchive.net/rcr/show/348.

T.
 
R

Robert Klemme

Logan said:
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
 
D

David Vallner

--------------enig02D796132252D971CE39A3D5
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Robert said:
Logan said:
Alternative decandence:

class Array
def to_hsh
require 'enumerator'
to_enum:)each_slice, 2).to_a.inject({}) { |h, (k, v)|
h.update(k=3D>v) }
end
end
=20
This seems a bit inefficient. If you write a method then I'd prefer
=20
require 'enumerator'
module Enumerable
def to_hash
h =3D {}
to_enum:)each_slice, 2).each {|k,v| h[k]=3Dv}
h
end
end
=20
irb(main):021:0> %w( a b c d ).to_hash
=3D> {"a"=3D>"b", "c"=3D>"d"}
irb(main):022:0> (1..10).to_hash
=3D> {5=3D>6, 1=3D>2, 7=3D>8, 3=3D>4, 9=3D>10}
=20

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 Vallner


--------------enig02D796132252D971CE39A3D5
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (MingW32)

iD8DBQFFRKjHy6MhrS8astoRAnWBAJsF0UsTiZjrDrIBoXslOB9jGfB6RgCdEoud
goAoKw2teM1P93eMds+E6+I=
=0ZOV
-----END PGP SIGNATURE-----

--------------enig02D796132252D971CE39A3D5--
 
L

Logan Capaldo

Logan Capaldo 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]
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.
 
L

Louis J Scoras

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.
 
R

Robert Klemme

David said:
Robert said:
Logan said:
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}

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
 
D

David Vallner

--------------enigBCC0175C63B7AE6037D9B452
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Robert said:
=20
I am not sure what you are at here. Object creation always costs - eve= n
small hashes. Reason is memory allocation and GC management overhead= =2E
=20

I meant that with clean blocks, to_enum:)each_slice, 2).to_a.inject({})
{ |h, (k, v)| h[k] =3D v) } might be the fastest variant because you coul=
d
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 Vallner


--------------enigBCC0175C63B7AE6037D9B452
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.5 (MingW32)

iD8DBQFFRUEdy6MhrS8astoRAvHQAJ4vZrxPiwKHSoZ/wmq8+9ENz7kqqgCeP7uu
hGJQxPjaiEr/GwuDzR4eJ3A=
=2SOa
-----END PGP SIGNATURE-----

--------------enigBCC0175C63B7AE6037D9B452--
 
R

Robert Klemme

Robert said:
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.

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
 
M

Martin DeMello

Logan said:
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

Never thought I'd see you speak out *against* inject :)

martin
 
R

Robert Klemme

Logan said:
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

Never thought I'd see you speak out *against* inject :)

Yeah, I must have been out of my mind. :) 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.

:)

Kind regards

robert
 

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

Forum statistics

Threads
474,216
Messages
2,571,120
Members
47,721
Latest member
MathewLoyd

Latest Threads

Top