Reputation: 892
A parameter defaulted to an empty hash attrs={}
returns an error:
can't convert Array into Hash
(TypeError)
I've tried this on Ruby versions 1.8.6, 1.8.7 and 1.9.1. A hash will be passed to 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
What am I doing wrong?
Upvotes: 2
Views: 4188
Reputation: 66837
Some notes:
Object
.if not
can more idiomatically be expressed as unless
.attrs
hash the last argument has the advantage that you can leave off the {}
around the hash elements when calling Category.new
. You can not do this if the hash is the middle, so it would make sense to show us your call to Category.new
.I changed your code accordingly:
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
Here's how you call it:
>> 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"}
This obviously has the problem that all other optional arguments have to be specified in order to be able to specify attrs
. If you don't want this, move attrs
back to the middle of the argument list and make sure to include the {}
in the call. Or even better, make the whole argument list a hash and merge it with the defaults args. Something like
class Category(opts = {})
# stuff skipped
@options = { :bla => 'foo', :bar => 'baz'}.merge(opts)
# more stuff skipped
end
Upvotes: 3