Skip to content

Instantly share code, notes, and snippets.

@tallakt
Last active December 26, 2015 04:49
Show Gist options
  • Save tallakt/7096060 to your computer and use it in GitHub Desktop.
Save tallakt/7096060 to your computer and use it in GitHub Desktop.
Ruby Hash from block
class Hash
class << self
def from_block()
Hash[Enumerator.new {|yielder| yield yielder }.to_a]
end
end
end
Hash::from_block do |yielder|
10.times {|i| yielder.yield "i:#{i}", i }
end
# irb(main):097:0> Hash::from_block {|y| 10.times {|i| y.yield "i:#{i}", i } }
# => {"i:0"=>0, "i:1"=>1, "i:2"=>2, "i:3"=>3, "i:4"=>4, "i:5"=>5, "i:6"=>6, "i:7"=>7, "i:8"=>8, "i:9"=>9}
# This is an example that does not modify the Hash class.
Enumerator.new {|y| 10.times {|i| y.yield i => i}}.reduce({}, &:merge!)
# irb(main):023:0> e = Enumerator.new {|y| 10.times {|i| y.yield i => i}}.reduce({}, &:merge!)
# => {0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5, 6=>6, 7=>7, 8=>8, 9=>9}
# The benefit of this structure is that you could have anything inside the Enumerator.new block that would
# normally be difficult to put in a loop.
Enumerator.new do |y|
10.times {|i| y.yield i => i}
y.yield a: "juhu"
10.times {|i| y.yield i*10 => i*10}
end.reduce({}, &:merge!)
# irb(main):001:0> Enumerator.new do |y|
# irb(main):002:1* 10.times {|i| y.yield i => i}
# irb(main):003:1> y.yield a: "juhu"
# irb(main):004:1> 10.times {|i| y.yield i*10 => i*10}
# irb(main):005:1> end.reduce({}, &:merge!)
# => {0=>0, 1=>1, 2=>2, 3=>3, 4=>4, 5=>5, 6=>6, 7=>7, 8=>8, 9=>9, :a=>"juhu", 10=>10, 20=>20, 30=>30, 40=>40, 50=>50, 60=>60, 70=>70, 80=>80, 90=>90}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment