No, there is not an #attributes
method for every Ruby class. The class you're using likely inherits from another class or mixes in a module which does (e.g. ActiveRecord::Base#attributes
).
That attributes method that you're defining will override any existing #attributes
method. In the case of an override, Ruby provides a #super
method, which calls the original method that you're overriding. In this case, you'll be calling the original #attributes
method which returns a Hash
of attributes keys and their values (e.g. { attr1: 'a', attr2: 'b' }
).
#merge
is a Hash function that you're calling on the Hash that the original #attributes
call returns (e.g { attr1: 'a', attr2: 'b' }
). #merge
creates a new hash consisting of the original attributes hash combined with the key-value pairs provided in the second hash.
From the Ruby 2.2 docs on Hash#merge
:
merge(other_hash) → new_hash click to toggle source
merge(other_hash){|key, oldval, newval| block} → new_hash
Returns a new hash containing the contents of other_hash and the
contents of hsh. If no block is specified, the value for entries with
duplicate keys will be that of other_hash. Otherwise the value for
each duplicate key is determined by calling the block with the key,
its value in hsh and its value in other_hash.
h1 = { "a" => 100, "b" => 200 }
h2 = { "b" => 254, "c" => 300 }
h1.merge(h2) #=> {"a"=>100, "b"=>254, "c"=>300}
h1.merge(h2){|key, oldval, newval| newval - oldval}
#=> {"a"=>100, "b"=>54, "c"=>300}
h1 #=> {"a"=>100, "b"=>200}
http://ruby-doc.org/core-2.2.0/Hash.html#method-i-merge
Some notes about your example: 'foo' => self.foo
- You don't need to specify
self
in self.foo
. foo
alone should suffice. That's really only needed for assignments self.foo = 'whatever'
and in cases where you've defined another foo
in the same scope.
- Make sure that they type of the key you're providing matches the type of the keys that
#attributes
is returning.
Case 1: #attributes
returns a Hash of Strings -> Values, so merge in a hash with String keys (ActiveRecord does this.)
{ 'attr1' => 1, 'attr2' => 'b' }.merge( { 'attr3' => '3' }
Case 2: #attributes
returns a Hash of Symbols -> Values, so merge in a hash with Symbol keys:
{ :attr1 => 1, :attr2 => 'b' }.merge( { :attr3 => '3' }