halfbit
halfbit

Reputation: 3954

reverse_merge returns hash instead of subclass. Is it a Bug or intended?

Summary: subclass.reverse_merge(class) returns class - not subclass

I have a small class extending Hash

class HtmlOptions < Hash
    def add_class 
    # add html-class like jQuery 
    …
    end

    (a little more)
end 

So if I am using it like that with merge

input_options = HtmlOptions.new(…)
…
input_options.merge(id:"ovewrite_id").add_class("sample") 

works as intended, while using reverse_merge

input_options = HtmlOptions.new(…)
input_options.reverse_merge(value:"default").add_class("sample")
#crashes

throws an error (add_class undefined).

Ok, passing HtmlOptions to both, does the trick like:

input_options.reverse_merge(HtmlOptions.new(value:"default")).add_class("sample")

So now I think this is a bug and correcting it in my HtmlOptions class is ok. Because I can not think about a situation where this silent class change is intended.

On the other hand, if it ist the basic idea of reverse_merge to work like that strictly reverse, I should not change it in my class (and the bang-version of reverse_merge is wrong)

Can anyone tell me if this behavior i intended?, (and maybe tell me where to use it?) Or just a bug.

Upvotes: 1

Views: 87

Answers (1)

DaveMongoose
DaveMongoose

Reputation: 905

reverse_merge is just what it says: the reverse of merge. The source code for it is:

def reverse_merge(other_hash)
  other_hash.merge(self)
end

That's why the result is the class of the object you pass in, rather than the object you're calling it with.

I think the best option would be to override reverse_merge for your HtmlOptions class; something like this:

def reverse_merge(other_hash)
  new(super)
end

Upvotes: 1

Related Questions