Альтернативная инициализация для класса, чтобы избежать обработки уже известной информации - PullRequest
1 голос
/ 04 июня 2010

У меня есть класс Autodrop, который содержит несколько методов, a.o. 'метаданные', которые вызывают внешний API (dropbox). Они медленные. Однако у меня уже часто есть эти метаданные при инициализации AutodropImage, поэтому я должен сделать методы умнее.

Я имею в виду следующее:

class Autodrop
  include Dropbox
  attr_reader :path

  def initialize(path)
    @path = path
  end

  def self.from_entry(drop_entry)
    @drop_entry = drop_entry
    self.initialize(@drop_entry.path)
  end

  def metadata
    if @drop_entry = nil
      return heavy_lifting_and_network_traffic
    else
      return @drop_entry.metadata
    end
  end
  #...
end

Теперь я ожидал бы позвонить

entry = BarEntry.new()
foo = Autodrop.from_entry(entry)
foo.metadata

Чтобы избежать этого тяжелого подъема и вызова сетевого трафика.

Но это не работает. И каким-то образом, во всей моей новизне, я уверен, что я не прав в этом все неправильно. Есть ли термин, который я должен искать и читать в первую очередь? Как бы вы пошли на это?

Обратите внимание, что примеры упрощены: в моем коде я наследую AutodropImage

Ответы [ 2 ]

1 голос
/ 04 июня 2010

Вы создаете переменную экземпляра @drop_entry в своем методе класса from_entry и, очевидно, он не будет доступен для вашего объекта, который вы создаете в этом методе. Одним из обходных путей является передача его в качестве параметра при инициализации класса. Должно работать, если вы делаете следующие модификации:

  1. В вашем from_entry изменении метода класса

    self.initialize(@drop_entry) 
    

    до

    new(@drop_entry)
    
  2. Изменить метод initialize на:

    def initialize(drop_entry)
      @drop_entry = drop_entry
      @path = @drop_entry.path
    end
    

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

    def initialize(path, drop_entry=nil)
0 голосов
/ 04 июня 2010

Вам потребуется кэшировать метаданные в переменной класса.

Редактировать: Или в переменной экземпляра уровня класса. Может быть, это чтение поможет: http://railstips.org/blog/archives/2006/11/18/class-and-instance-variables-in-ruby/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...