Biorąc pod uwagę klejnot, który definiuje klasy najwyższego poziomu, które kolidują z pisanym przeze mnie kodem, możliwe jest wymaganie klejnotu w taki sposób, aby wszystkie jego klasy zostały zgrupowane w module Mogę zdefiniować? Na przykład, jeśli unsafe_gem definiuje klasę:Załaduj klejnotu ruby do przestrzeni nazw zdefiniowanej przez użytkownika
class Word
# ... some code
end
musiałbym coś takiego:
class Word
# My word class.
end
module SafeContainer
# This obviously doesn't work
# (i.e. the gem still defines ::Word).
require 'unsafe_gem'
end
tak, że można rozróżnić:
Word.new # => The class I defined.
SafeContainer::Word.new # => The class defined by the gem.
niektórych dalszych szczegółów: Mój kod (np. Klasa "Word") jest już zapakowany w swoją własną przestrzeń nazw. Chciałbym jednak móc udostępnić użytkownikowi opcję włączania formy "cukru syntaktycznego", dzięki czemu niektóre klasy są bezpośrednio dostępne w obszarze nazw najwyższego poziomu. Powoduje to jednak konflikt nazwy z jednym z klejnotów, z których korzystam, który definiuje klasę najwyższego poziomu. Żadne z obecnie proponowanych rozwiązań nie działa, ponieważ gem faktycznie opiera się na swojej globalnie zdefiniowanej klasie; więc undefining klasy łamie klejnot. Oczywiście klejnot ma więcej niż jeden plik, a indywidualne zapotrzebowanie na jego pliki w module wydaje się bardzo kruchym rozwiązaniem. Obecnie jedyne obejście, które znalazłem, to:
begin
# Require the faulty gem.
require 'rbtagger'
rescue
# If syntactic sugar is enabled...
if NAT.edulcorated?
# Temporarily remove the sugar for the clashing class.
Object.const_unset(:Word); retry
else; raise; end
ensure
# Restore syntactic sugar for the clashing class.
if NAT.edulcorated?
Object.const_set(:Word, NAT::Entities::Word)
end
end
Nie wiem dlaczego, ale to powoduje, że moje paznokcie się zwijają. Ktoś ma lepsze rozwiązanie?