Это неправильно, но почему (и как я могу заставить его течь лучше)? - PullRequest
1 голос
/ 02 марта 2012

Итак, я выясняю, как настроить некоторые параметры для класса.'options' - это хешЯ хочу

1) отфильтровать опции, которые мне не нужны или не нужны

2) установить некоторые переменные экземпляра для использования в другом месте

3) и установить другой хеш собработанные параметры как @ current_options.

def initialize_options(options)
  @whitelisted_options, @current_options  = [:timestamps_offset, :destructive, :minimal_author], {}
  n_options = options.select { |k,v| @whitelisted_options.include?(k) }
  @current_options[:timestamps_offset] = @timestamp_offset = n_options.fetch(:timestamps_offset, 0)*(60*60*24)
  @current_options[:destructive] = @destructive = n_options.fetch(:destructive, false)
  @current_options[:minimal_author] = @minimal_author = n_options.fetch(:minimal_author, false)
end

Я предполагаю, что это немного много, независимо от того, что я передаю, я получаю:

{:timestamps_offset=>0, :destructive=>false, :minimal_author=>false}

Когда я делаю эту строкустрока из командной строки, она работает так, как я хочу, но не в моем классе.Итак, что происходит и как мне это убрать?

РЕДАКТИРОВАТЬ: это на самом деле работает без участия класса, в котором я его использую, но внутри это не так, что реальность - это то, что происходит, яЯ не знаю прямо сейчас.

attr_reader: current_options - это то, как это установлено в классе, возможно, это требует некоторой ревизии.

EDIT2: строка 2 метода должна выбираться из@ whitelisted_options

РЕДАКТИРОВАТЬ3: На самом деле оказалось то, о чем я не думал ... "параметры" анализируются из файла yaml как строки .... и я выбирал символы, меняя их вокругИмеет значение то, что до того, как метод искал символы и не находил ни одного, например, «деструктивный» vs: деструктивный, поэтому всегда по умолчанию используется значение по умолчанию.Короче говоря, мне просто нужно было обозначать хеш-ключи при импорте параметров.

Ответы [ 2 ]

1 голос
/ 02 марта 2012

Ваш @current_options инициализируется как пустой хеш. Когда вы фильтруете options, переданный в качестве параметров, ни один из ключей не будет присутствовать в @current_options, поэтому n_options окажется пустым.

Затем, когда вы установите @current_options в следующих строках, он всегда будет получать значения по умолчанию (0, false, false), и поэтому ваш вывод всегда одинаков.

Вы решаете эту проблему путем условной инициализации @current_options, чтобы она была установлена ​​на {} только один раз:

@ current_options || = {}

Редактирование после операции:

Ваша проблема с options.select - в Ruby 1.8 он не возвращает хэш, а скорее массив. Ваши вызовы fetch всегда будут неудачными (поскольку символы не могут быть индексами массива), поэтому всегда возвращаются значения по умолчанию.

Вместо этого попробуйте:

n_options = options.inject({}) {|h, p| h[p[0]] = p[1] if @whitelisted_options.include? p[0]; h } 

где p - массив, содержащий каждую пару ключ / значение.

В Ruby 1.9.2 Hash.select ведет себя так, как вы ожидали.

Редактировать 2: Вот как я подхожу к этому:

class Foo
  @@whitelisted_options= {:timestamps_offset => 0, :destructive => false, :minimal_author =>false}

  @@whitelisted_options.keys.each do |option|
    define_method(option) { return @current_options[option] rescue nil}
  end

  def initialize_options(options)
    @current_options = {}
    @@whitelisted_options.each {|k, v| @current_options[k] = options[k] || v}
    @current_options
  end
end

Используется:

f = Foo.new
f.destructive #=> nil
f.initialize_options(:minimal_author => true, :ignore => :lol)
f.destructive #=> false
f.minimal_author #=> true
f.timestamps_offset #=> 0
0 голосов
/ 02 марта 2012
  1. Для чего @whitelisted_options? 1003 *
  2. Что вы хотите сделать, если :destructive не является ключом в options? Вы хотите иметь :destructive => false, или вы хотите, чтобы @current_options вообще не упоминал :destructive?
...