David West David West - 6 months ago 10
Ruby Question

Ruby - Singleton module with each. Returning a value gives an Enumerator. How can I get the value instead?

Example code:

module Creatures
class << self
def to_h
{
squirtle: {full_name: 'Squirtle T. Turtle'},
pikachu: {full_name: 'Pikachu B. Pikachu'}
}
end
def keys
to_h.keys
end
def collect
to_h.keys.collect
end
def each
to_h.keys.each
end
end
end

module CompanionHelper
def get_companion_creature_experience(companion_data)
Creatures.each do |creature|
return companion_data[creature]["#{creature}_experience".to_sym] if companion_data.has_key?(creature)
end
end
end

include CompanionHelper
companion_data = {squirtle: {squirtle_experience: 8000}}

get_companion_creature_experience(companion_data)


Forgive me if the example is contrived. The original code is from the insurance world but I can't copy and paste it :)

The crux of the problem is I want to use
Creatures.each
in another module, pass it a block, and have it work just like
Creatures.keys.each
would work (i.e. w/ the given example companion data I get 8000 for
get_companion_creature_experience(companion_data)
.

Currently I get
Enumerator
instead.

Answer

Problem is that to_h.keys.each returns Enumerator which does not expect any arguments. Pass a block inside each since you want to use it:

def each &block
  to_h.keys.each &block
end

Or you can yield it:

def each
  to_h.keys.each do |k|
    yield k
  end
end

Anyway, edit your code in helper by deleting return statement

Comments