Ruby 数组#样本随机数生成器

Ruby 数组#样本随机数生成器,ruby,Ruby,如果将范围作为随机数生成器传递,那么Array#sample如何工作? 如下: > [*1..10].sample(random: 1..3) =>9 根据文档,rng不是您可能认为的范围对象rng是一个随机数生成器 可选的rng参数将用作随机数生成器 重点是#sample,将其第二个参数作为关键字参数。如果我们使用类似于foo:12或rng:(1..2),它将给出参数错误:未知关键字:。只有将可选参数作为random:object或响应的对象提供值时,才可以接受该参数。请记住,对

如果将范围作为随机数生成器传递,那么
Array#sample
如何工作? 如下:

> [*1..10].sample(random: 1..3)
=>9
根据文档,
rng
不是您可能认为的
范围
对象
rng
是一个随机数生成器

可选的rng参数将用作随机数生成器

重点是
#sample
,将其第二个参数作为关键字参数。如果我们使用类似于
foo:12
rng:(1..2)
,它将给出参数错误:未知关键字:。只有将可选参数作为
random:object或响应的对象提供值时,才可以接受该参数。请记住,对于第二个参数,您告诉
#sample
,在没有可选参数的情况下使用随机数生成器,而不是它使用的默认值

以下是RNG的一个自定义实现:


因此,从上面的调用堆栈中,您可以看到-
Array#sample
方法已被调用。现在在内部,Ruby在
范围
对象上调用了
内核#rand
。现在,
(1..3).respond_to?
返回
false
(因为
#rand
-它是
范围
的一个私有实例方法),这就是为什么最后调用了
#respond_to_missing?
方法来执行此任务。

因此此方法检查
示例(随机:rng)中的
rng
实际上是一个随机数生成器吗?你能解释一下吗?@zero7的意思是什么?我给你举了一些例子。。仍然不相信……:)How-就方法如何知道而言,提供的值实际上是一个随机数生成器,而不是一个范围对象(例如)。我理解你的例子,我不是故意粗鲁的。只是好奇这个方法是如何忽略可选参数的。通过键
random
。。。它会理解的,很好。看起来不错。我想提高投票率,但我已经做到了,不能再提高两次
a = (1..10).to_a
r = Random.new
r2 = r.dup
a1 = a.sample(random: r)
a2 = a.sample(random: r2)
a1 == a2 # => true
r = 1..3
a1 = [*1..10].sample(random: r)
a2 = [*1..10].sample(random: r)
a1 == a2 # => false
ob = Object.new

def ob.to_int
  5000
end

gen_to_int = proc do |max|
  ob
end

class << gen_to_int
  alias rand call
end

ary = (0...10000).to_a

ary.sample(random: gen_to_int) # => 5000
ary.sample(random: gen_to_int) # => 5000
ary.sample(random: gen_to_int) # => 5000
trace = TracePoint.new(:c_call) do |tp|
  p [tp.lineno, tp.defined_class, tp.method_id, tp.event]
end

trace.enable do
  [1,2,3,4,5,66,4].sample(random: 1..3)
end
# >> [6, Array, :sample, :c_call]
# >> [6, Kernel, :rand, :c_call]
# >> [6, Kernel, :respond_to_missing?, :c_call]