2016-12-12 2 views
0

Я просматриваю API Facets и выбираю некоторые методы для включения в мою библиотеку исправлений, совместимую с исправлениями.Использование уточнений для исправления основного модуля, такого как Kernel

Я попал в ловушку, пытаясь исправить ядро. Это модуль, в то время как другие вещи я заплата была классов (String, массив и т.д.)


Вот доказательство того, что не может не может быть уточнена с помощью моего стандартного подхода к основным классам:

module Patch 
    refine Kernel do 
    def patched? 
     true 
    end 
    end 
end 

# TypeError: wrong argument type Module (expected Class) 
# from (pry):16:in `refine' 

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

class MyKernel 
    include Kernel 
    extend Kernel 
end 

# not sure if Object::Kernel is really the global reference 
Object::Kernel = MyKernel 

module Patch 
    refine MyKernel do 
    def patched? 
     true 
    end 
    end 
end 

class Test 
    using Patch 
    patched? 
end 
# NoMethodError: undefined method `patched?' for Test:Class 
# from (pry):15:in `<class:Test>' 

В этом случае я мог бы успешно получить ту же функциональность, заменив ядро ​​с помощью объекта:

module Patch 
    refine Object do 
    def patched? 
     true 
    end 
    end 
end 

class Test 
    using Patch 
    patched? 
end 

Но я не уверен, если я мог бы получить эту эквивалентность с другими основными модулями таких как Перечислимый.

ответ

0

Как я упоминал в вопросе, можно выполнить функциональный эквивалент расширения модуля ядра, вместо этого используя класс Object.

Другой пример, который я дал был перечислимого модуль, который оказывается практически можно расширить с помощью класса Enumerator:

module Patch 
    refine Enumerator do 
    def patched? 
     true 
    end 
    end 
end 

class Test 
    using Patch 
    Array.new.to_enum.patched? 
end 

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

В этом случае я мог бы проверить с Enumerator < Enumerable, который возвращает истинное, потому что класс Enumerator включает Enumerable модуль (хотя он не проверяет, если он был продлен)


Чтобы обновить посмотрев на corefines источник , Я нашел полезный метод для поиска всех классов, которые включают в себя модуль

classes_including_module

Смежные вопросы