Skip to content

TypeError with Prime.each_with_index and mass assignment #744

sferik opened this Issue May 18, 2013 · 4 comments

3 participants

sferik commented May 18, 2013

I have written a simple program to find clean chains of prime numbers:

require 'prime'

Prime.each_with_index.inject(0) do |sum, (number, index)|
  puts index + 1 if sum % number == 0
  sum += number

This program runs on MRI 1.9+ but fails on JRuby 1.7 with the following error:

TypeError: Array can't be coerced into Fixnum
                % at org/jruby/
           (root) at clean_chains.rb:4
             call at org/jruby/
             each at /Users/sferik/.rbenv/versions/jruby-1.7.4/lib/ruby/1.9/prime.rb:287
             loop at org/jruby/
             each at /Users/sferik/.rbenv/versions/jruby-1.7.4/lib/ruby/1.9/prime.rb:286
             each at /Users/sferik/.rbenv/versions/jruby-1.7.4/lib/ruby/1.9/prime.rb:149
         __send__ at org/jruby/
             each at /Users/sferik/.rbenv/versions/jruby-1.7.4/lib/ruby/1.9/forwardable.rb:201
  each_with_index at org/jruby/
             each at org/jruby/
           inject at org/jruby/
           (root) at clean_chains.rb:3

The program does not crash (and runs as expected) if I replace Prime with the array:

[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71]

I get a similar error on MRI if I remove the parentheses, which leads me to believe the issue is related to destructuring assignment in conjunction with the way Prime.each_with_index is implemented in JRuby.

JRuby Team member

When an Enumerator is used, the value assigned to number is different.


Hey @BanzaiMan, I'm just putting the finishing touches on a fix for this. The root cause here is a bad arity assumption in RubyEnumerable#each_with_indexCommon which only comes into play when each is implemented with a call rather than a yield (as it is in Prime). Here's a minimal repro scenario:

one_args_each = do
  include Enumerable
  def each(&block)
    yield "yield arg has the correct type""call arg is wrapped in an array with an extra nil")
end do |each_args, index|
  p each_args

Will send the pull once I've finished validating a few things... just wanted to give you the heads up since you commented so that we don't dupe work.

JRuby Team member

@dmarcotte I would be busy the rest of the way today, so your contribution is welcome!


Glad to help @BanzaiMan! Just sent pull #807. Check it out for even more context on what's going on here.

@BanzaiMan BanzaiMan closed this in #807 Jun 17, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.