Детерминированный массив перекрестных реализаций # shuffle

Можно передать генератор случайных чиселArray#shuffle это делает тасовку детерминированной.

Например, в МРТ 1.9.3p327:

[1, 2, 3, 4].shuffle(random: Random.new(0)) # => [1, 2, 4, 3]
[1, 2, 3, 4].shuffle(random: Random.new(0)) # => [1, 2, 4, 3]

Тем не менее, реализация генератора случайных чисел Random isn 'т указан. Из-за этого другие реализации Ruby имеют разные результаты.

В Rubinius 2.0.0rc1 (выпуск 1.9.3 2012-11-02 JI):

[1, 2, 3, 4].shuffle(random: Random.new(0)) # => [1, 3, 2, 4]
[1, 2, 3, 4].shuffle(random: Random.new(0)) # => [1, 3, 2, 4]

Кстати, jruby-1.7.1 использует тот же генератор случайных чисел, что и MRI 1.9.3p327, но это случайно, а не гарантировано.

Для обеспечения детерминированного тасования согласованной реализации, я хотел бы передать пользовательский генератор случайных чисел вArray#shuffle, Я думал, что это будет тривиально, но оказывается, что это довольно сложно.

Вот что я попробовал сначала, в МРТ:

class NotRandom; end
[1, 2, 3, 4].shuffle(random: NotRandom.new) # => [4, 3, 2, 1]
[1, 2, 3, 4].shuffle(random: NotRandom.new) # => [4, 2, 1, 3]

Я ожидалNoMethodError говоря мне интерфейс, который мне нужно было реализовать.

Есть идеи?

ОБНОВИТЬ:

Как указывает @glebm,NotRandom унаследованныйKernel#rand, который интерфейс необходим. Это легко обойти, но, к сожалению, не предлагает решения.

class NotRandom
  def rand(*args)
    0
  end
end

В RBX:

[1, 2, 3, 4].shuffle(random: NotRandom.new) # => [1, 2, 3, 4]

В МРТ:

[1, 2, 3, 4].shuffle(random: NotRandom.new) # => [2, 3, 4, 1]

Ответы на вопрос(1)

Ваш ответ на вопрос