Пустой хеш как параметр по умолчанию превращается в массив? - PullRequest
2 голосов
/ 19 апреля 2011

Параметр по умолчанию пустой хэш attrs={} возвращает ошибку:

can't convert Array into Hash
(TypeError)

Я пробовал это на Ruby версий 1.8.6, 1.8.7 и 1.9.1. Хеш будет передан в attrs.

class Category < Object   

  attr_accessor :attributes  
  attr_accessor :rel_attrs  
  attr_accessor :cls_str

  def initialize (term='',title='', attrs={}, scheme = '', rel=[], cls_str='')

    @attributes ={}
    @attributes['scheme']  = scheme
    @attributes['term']    = term
    @attributes['title']   = title
    @attributes['related'] = rel
    @cls_str = cls_str

    if not attrs.empty?
       @attributes.update attrs
    end
  end
end

Что я делаю не так?

1 Ответ

3 голосов
/ 19 апреля 2011

Некоторые заметки:

  • Вам не нужно наследовать от Object.
  • if not может быть более идиоматически выражено как unless.
  • Создание хеша attrs последним аргументом имеет то преимущество, что вы можете пропустить {} вокруг элементов хеша при вызове Category.new. Вы можете не делать это, если хеш находится посередине, поэтому имеет смысл показать нам ваш вызов Category.new.

Я изменил ваш код соответственно:

class Category 

  attr_accessor :attributes
  attr_accessor :rel_attrs  
  attr_accessor :cls_str

  def initialize (term='',title='', scheme = '', rel=[], cls_str='', attrs={})

    @attributes ={}
    @attributes['scheme']  = scheme
    @attributes['term']    = term
    @attributes['title']   = title
    @attributes['related'] = rel
    @cls_str = cls_str

    @attributes.update(attrs) unless attrs.empty?
  end
end

Вот как вы это называете:

>> c = Category.new("term", "title", "scheme", [1,2,3], 'cls_string', :foo => 'bar', :baz => 'qux') 
#=> #<Category:0x00000100b7bff0 @attributes={"scheme"=>"scheme", "term"=>"term", "title"=>"title", "related"=>[1, 2, 3], :foo=>"bar", :baz=>"qux"}, cls_str"cls_string"
>> c.attributes 
#=> {"scheme"=>"scheme", "term"=>"term", "title"=>"title", "related"=>[1, 2, 3], :foo=>"bar", :baz=>"qux"}

Очевидно, что проблема заключается в том, что все остальные необязательные аргументы должны быть указаны, чтобы можно было указать attrs. Если вы не хотите этого, переместите attrs обратно в середину списка аргументов и обязательно включите {} в вызов. Или, что еще лучше, сделайте весь список аргументов хэшем и объедините его с аргументами по умолчанию. Что-то вроде

 class Category(opts = {})
   # stuff skipped
   @options = { :bla => 'foo', :bar => 'baz'}.merge(opts)
   # more stuff skipped
 end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...