Как предотвратить переопределение классов в Ruby? - PullRequest
0 голосов
/ 23 мая 2019

Я устанавливаю правила написания мини-наборов и хочу запретить другим программистам переопределять методы для существующих классов, потому что это повлияет на другие тесты, где будет использоваться этот класс.Вот некоторые пояснения ниже.

Например, у меня есть класс в папке lib, KlassExample .У него есть открытый метод do_something с собственной логикой.В мини-тесте кто-то может захотеть переопределить этот метод с помощью другой логики.Я хочу запретить запуск теста, если логика класса была переопределена.

Примеры кода:

lib / klass_example.rb

class KlassExample

  def do_something
    false
  end

end

test / unit / lib / klass_example_test.rb

require 'unit/test_helper'
require 'klass_example'

class KlassExample

  def do_something
    true
  end

end

class KlassExampleTest < Minitest::Test

  def test_do_something
    assert_equal true, KlassExample.new.do_something
  end

end

Я хочу, чтобы программисты использовали MiniTest :: Mock вместо переопределения класса, поэтому мне нужен некоторый принудительныйдействия, чтобы заставить их правильно писать код.

Есть ли какое-нибудь сложное решение, как это сделать?

1 Ответ

3 голосов
/ 23 мая 2019

Хотя этот конкретный случай использования может быть несколько покрыт TracePoint#new(:class), установив TracePoint при повторном открытии класса и, например, Поднимаясь оттуда, вы бы никогда не помешали всем возможностям, явно и неявно встроенным в Ruby, действительно позволять разработчикам делать все, что они хотят.

Перезаписанный Module#prepended обратный вызов запретил бы другим prepend модулям вашего класса:

KlassExample.prepend(Module.new { def self.prepended(*); raise end })

Существуют способы предотвращения Module#define_method вызовов, также они уже выглядят как хаки.

Но весь набор возможностей обмануть вашу охрану практически безграничен, поэтому я сомневаюсь, что это вообще выполнимо. Бьюсь об заклад, каждый раз, когда ты думаешь: «Хорошо, теперь все покрыто», я бы легко придумал другой неуклюжий способ обойти всех своих охранников.

Ruby не является языком, разработанным для предотвращения разработчиками того, что они хотят.

...