2009-11-27 2 views
0

Я пытаюсь выгрузить библиотеку из ruby ​​1.8. Я не писал библиотеку. Я могу изменить API, если это абсолютно необходимо, но у него действительно много пользователей, которых я бы предпочел не причинять неудобства.сохранение видимости при выполнении alias_method_chain на attr_accessor в Ruby 1.9

Вот проблема упрощается:

require 'rubygems' 
require 'activesupport' 

class Foo 
    private 
    def self.attr_accessor_with_magic(*attrs) 
    attr_accessor_without_magic(*attrs) 
    end 

    public 
    class << self 
    alias_method_chain :attr_accessor, :magic 
    end 

    attr_accessor :bar 
end 

foo=Foo.new 
foo.bar=17 
puts foo.bar 

На Руби 1.8.7p174, это печатает 17

На Руби 1.9.1p243, я получаю private method ``bar=' called for #<Foo:0x000000010a40f8> (NoMethodError)

Очевидно, что поведение Ruby 1.9 является правильным , Чтобы лучше проиллюстрировать ошибку Ruby 1.8, замените public на private в приведенном выше коде. Ruby 1.8 все еще печатает 17!

Поэтому я могу сохранить «совместимость ошибки» с текущей версией библиотеки, написав

private 
    def self.attr_accessor_with_magic(*attrs) 
    public 
    attr_accessor_without_magic(*attrs) 
    private 
    end 

Кто-нибудь есть какие-либо идеи, как я могу сделать правильно и создать соответствующую видимость для ATTR? На Ruby 1.8 это будет public независимо от того, что я делаю, но возможно ли сделать правильную вещь для 1.9?

ответ

0

Если attr_accessor не подходит для вас, вам не нужно его использовать. Насколько мне известно, запись attr_accessor :bar - это просто быстрый способ определить два общедоступных метода: «bar» и «bar =», которые получают и устанавливают переменную-член @bar. Таким образом, вы можете сделать это вручную, а также добавить свои собственные настройки и уровни конфиденциальности:

class Foo 
    public 
    def bar 
    reading_bar_magic() 
    return @bar 
    end 

    private 
    def bar=(value) 
    setting_bar_magic() 
    @bar=value 
    end 
end 
+0

Я не понимаю? Предоставляет ли ваша библиотека «attr_accessor_with_magic» для использования пользователем или предоставляет класс с именем Foo с помощью аксессуара под названием «bar»? –

+0

библиотека предоставляет метод, называемый 'attr_accessor'. Он работает так же, как и «attr_accessor» модуля, за исключением того, что он позволяет передавать несколько дополнительных параметров. –

+0

или, по крайней мере, он должен работать одинаково. Но это не так - это не может сохранить видимость. Таким образом, вопрос. –

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