/ / Desativando a reprodução aleatória e a amostra na classe Array - ruby

Desativando o shuffle e a amostra na classe Array - ruby

Suponhamos que queremos que alguém escreva seu próprio método pseudoaleatório. Como exercício de programação. E queremos gerar um erro cada vez que eles tentam resolver as funções internas como atalho.

Até agora, é isso que eu fiz:

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|
eval
"""
def #{method}
raise ERROR_STRING_FOR_RANDOM
end
"""
end

Então, ele bloqueia o Random e isso gera um erro:

rand
srand
Random.new.rand(18)

mas não funciona com métodos pseudo-aleatórios de matriz. Por exemplo

[1,2,3].shuffle!

Ainda funciona. Por que isso acontece e como evitá-lo?

Respostas:

2 para resposta № 1

Você pode abrir a classe e substituir os métodos que deseja desativar ...

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 para resposta № 2

Seu código estava recebendo erro

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

mas para outras funções de módulo semelhantes, você pode apenas definir os métodos como

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

deve ser parecido

 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"]

Agora, se você ligar

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

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

espero que isso ajude você

Se você quiser manter o seu caminho

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

Agora você pode obter tudo

> 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

0 para resposta № 3

Está bem. Isso funciona:

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

Usar operadores de resolução de escopo era uma idéia errada para começar. Eles apenas criam constantes dentro de classes em vez de redefinir métodos

Da mesma forma, a maneira correta de desativar rand e srand é assim:

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