空哈希作为默认参数变成数组?

时间:2011-04-19 08:13:42

标签: ruby

默认为空哈希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 个答案:

答案 0 :(得分:3)

一些注意事项:

  • 您不必继承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移回参数列表的中间位置,并确保在调用中包含{}。或者甚至更好,使整个参数列表成为哈希并将其与默认值args合并。像

这样的东西
 class Category(opts = {})
   # stuff skipped
   @options = { :bla => 'foo', :bar => 'baz'}.merge(opts)
   # more stuff skipped
 end