2014-01-04 4 views
0

Я использую RMagick и мне не нравится одно:Расширение/изменение библиотеки

Когда я делаю:

Magick::ImageList.new(path) 

путь всегда должен быть локальный файл. Так, в моем коде я много раз повторял это:

if URI(path).host.nil? 
    Magick::ImageList.new(path) 
else 
    url_image = open(path) 
    image = Magick::ImageList.new 
    image.from_blob(url_image.read) 
end 

Как следует управлять этим кодом, чтобы избежать повторения каждый раз, я хочу, чтобы создать новый объект Magick :: ImageList? Кстати, я использую Rails.

+0

Почему бы не извлечь повторяющийся код в модуль? – jcm

+0

Используйте модуль или метод, но получите его в одном месте и многократно вызывайте ЭТО. В противном случае это приведет к созданию грязного кода. –

+0

Покажите нам образцы «пути», которые активируют разделы 'if' и' else'. –

ответ

0

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

Возможно, что-то вдоль этих линий:

class MySuperRadImageList 
    def self.open(path) 
    image_list = if URI(path).host.nil? 
        Magick::ImageList.new(path) 
       else 
        Magick::ImageList.new.from_blob(open(path).read) 
       end 
    self.new(image_list) 
    end 

    def initialize(image_list) 
    # ... 
    end 
end 

Я бы рекомендовал рефакторинг кода выше, но хотел бы показать вам конкретный пример того, что я предлагал (особенно ту линию в else пункте o.o).

+0

Если я это сделаю, что делать, если я хочу вызвать метод экземпляра Magick? Мне нужно было бы создать методы в моем MySuperRadImageList для всех методов экземпляра Magick? –

+0

Да, или вы можете использовать что-то вроде модуля Ruby's [Delegate] (http://apidock.com/rails/Module/delegate), который обеспечивает простой способ сделать именно это. Это также делает очень ясным в коде, что происходит. – csexton

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