Implementierungsübergreifendes deterministisches Array # shuffle

Es ist möglich, einen Zufallszahlengenerator an zu übergebenArray#shuffle das macht das mischen deterministisch.

Zum Beispiel in MRI 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]

Die Zufallszahlengenerator-Implementierung von Random ist jedoch nicht angegeben. Aus diesem Grund haben andere Implementierungen von Ruby andere Ergebnisse.

In Rubinius 2.0.0rc1 (1.9.3 Release 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 verwendet übrigens den gleichen Zufallsgenerator wie MRI 1.9.3p327, dies ist jedoch nur zufällig und nicht garantiert.

Um ein konsequentes, implementierungsübergreifendes, deterministisches Mischen zu erreichen, möchte ich einen benutzerdefinierten Zufallszahlengenerator übergebenArray#shuffle. Ich dachte, das wäre trivial, aber es stellt sich als ziemlich kompliziert heraus.

Folgendes habe ich zuerst in der MRT versucht:

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]

Ich habe ein erwartetNoMethodError Erzählen Sie mir die Schnittstelle, die ich implementieren musste.

Irgendwelche Einsichten?

AKTUALISIEREN:

Wie @glebm darauf hinweist,NotRandom vererbtKernel#rand, welches die Schnittstelle benötigt. Dies lässt sich leicht umgehen, bietet aber leider keine Lösung.

class NotRandom
  def rand(*args)
    0
  end
end

In RBX:

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

In der MRT:

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

Antworten auf die Frage(1)

Ihre Antwort auf die Frage