在Array类中禁用shuffle和sample

时间:2016-04-07 14:00:19

标签: ruby

假设我们希望有人编写自己的伪随机方法。作为编程练习。我们希望每次尝试将内置函数解析为快捷方式时都会引发错误

到目前为止,这就是我所做的:

rand
srand
Random.new.rand(18)

因此,它会阻止随机,这会引发错误:

[1,2,3].shuffle!

但它不适用于数组的伪随机方法。例如

// Create a queue with duplicate detection
// with a detection history window of one hour,
// and requires sessions.

QueueDescription rfidCheckoutQueueDescription = new QueueDescription("rfidcheckout")
{

    RequiresSession = true,

    RequiresDuplicateDetection = true,

    DuplicateDetectionHistoryTimeWindow = new TimeSpan(0, 1, 0)

};

// Create a queue that supports duplicate detection.
namespaceMgr.CreateQueue(rfidCheckoutQueueDescription);

仍然有效。为什么会发生这种情况以及如何预防?

3 个答案:

答案 0 :(得分:2)

您的代码出错了

ArgumentError: wrong number of arguments (0 for 1..4)

但是对于其他类似的模块函数,您可以定义类似

的方法
methods_to_block = ["rand", "srand","seed", "sample", "shuffle!", "shuffle!"]

应该看起来像

 methods_to_block.each do |method|
   define_method "#{method}" do
     raise ERROR_STRING_FOR_RANDOM
   end
 end
 #=> ["rand", "srand", "Random::rand", "Random::srand", "Random::seed", "Random::new", "Kernel::rand", "Kernel::srand", "Array::shuffle", "Array::shuffle!", "Array::sample"]

现在,如果你打电话

> srand
RuntimeError: Usage of built-in random generators is not allowed

> rand
RuntimeError: Usage of built-in random generators is not allowed

希望它会帮助你

如果你想坚持下去

ERROR_STRING_FOR_RANDOM = "Usage of built-in random generators is not allowed"

methods_to_block = ["rand", "srand", "Random::rand", "Random::srand", 
"Random::seed", "Random::new", "Kernel::rand", "Kernel::srand",
"Array::shuffle", "Array::shuffle!", "Array::sample"]


methods_to_block.each do |method|
if method.split("::").size > 1 && method.split("::").first != "Kernel"
class_name = method.split("::").first
method_name = method.split("::").last
er = <<ER
class #{class_name}
def #{method_name}
raise ERROR_STRING_FOR_RANDOM
end
end
ER
eval(er)
else
define_method "#{method}" do
raise ERROR_STRING_FOR_RANDOM
end
end
end

现在你可以得到所有

> srand
RuntimeError: Usage of built-in random generators is not allowed

> rand
RuntimeError: Usage of built-in random generators is not allowed

> [2,3,4,5].shuffle
RuntimeError: Usage of built-in random generators is not allowed

答案 1 :(得分:2)

您可以打开课程并替换您要禁用的方法......

class Array
  ERROR_STRING_FOR_RANDOM = "Usage of built-in random generators is not allowed"
  RANDOM_METHODS = [:shuffle, :shuffle!, :select]
  def rajarshi_random_error
    raise ERROR_STRING_FOR_RANDOM
  end
  RANDOM_METHODS.each do |m|
    define_method(m) {|*args| rajarshi_random_error }
  end 
end

答案 2 :(得分:0)

确定。这有效:

class Array
  undef_method :sample, :shuffle, :shuffle!
end

使用范围解析运算符是错误的想法开始。它们只是在类中创建常量而不是重新定义方法

同样,禁用rand和srand的正确方法如下:

module Kernel
  undef_method :rand, :srand
  class << self
    undef_method :rand, :srand
  end
end

class Random
  undef_method :rand, :srand, :seed
  class << self
    undef_method :rand, :srand, :new
  end
end