Error: undefined method "each" for String when running elastic-mapreduce specifying distributed cache file

2.5k views Asked by At

I've got the following error:

Error: undefined method `each' for "s3n://dico-count-words/Cache/dicoClazz.p#dicoClazzCache.p":String

When I run the following command line to launch a mapreduce algorithm on Amazon EMR cluster via elastic-mapreduce, specifying a distributed cache file:

    ./elastic-mapreduce --create --stream \
> --input s3n://dico-count-words/Words \
> --output s3n://dico-count-words/Output \
> --mapper s3n://dico-count-words/Code/mapper.py \
> --reducer s3n://dico-count-words/Code/reducer.py \
> --log-uri s3n://dico-count-words/Logs \
> --cache s3n://dico-count-words/Cache/dicoClazz.p#dicoClazz.p

I followed the instructions I found here. I haven't had any issue running similar commands to create others clusters which didn't need distributed cache file. I have also managed to run this very job using the AWS console. But I would prefer to do it via the CLI. I think it might be an issue with ruby similar to this one. But I don't know aything about ruby so it's just a guess. It's also the first time that I use AWS and so elastic-mapreduce. For your information, this is the version of ruby I have:

ruby 2.0.0p451 (2014-02-24 revision 45167) [universal.x86_64-darwin13]

Do you have any ideas about where that error is coming from? Any suggestions to fix it?

Many thanks.

1

There are 1 answers

0
cdownard On

each is not available for the ruby String class.

As an example, let's look at the following:


x = "test"
x.each {|character| puts character}
>>>NoMethodError: undefined method `each' for "test":String

This is what you're seeing in your code, and that's to be expected. Open irb in your terminal and try the following:

2.0.0-p247 :001 > x = "test"
2.0.0-p247 :002 > x.each <now hit tab twice>


2.0.0-p247 :003 > x.each_
x.each_byte       x.each_char       x.each_codepoint  x.each_line

You should see something close to the above. I happen to be using ruby 2.0.0-p247. Your version may differ.

irb supports auto complete. Here we started typing each and irb is making suggestions based on available options that start with each. As you can see, just plain each is not in fact an option. Instead, think of a string as an array of characters. That is "test" can be thought of like ["t", "e", "s", "t"]. Given this representation, it's obvious what x.each_char will do - it will yield each character in the string. Thus:

x.each_char {|c| puts c}

will of course print each character of the string.

If we can see some of the code and data moving through it, it would be easier to suggest a solution for you. However, the above explanation is the reason you are throwing an error when calling .each on a String.

I hope this is helpful.