Eamon Nerbonne
Eamon Nerbonne

Reputation: 48086

Calling a mixin's method on an object that doesn't include that mixin

I'd like to use some handy util methods; in particular Enumerable#to_a on objects that satisfy the Enumerable contract (i.e. implement each), but that do not include Enumerable.

I've figured out that this seems to work:

Enumerable.instance_method(:to_a).bind(obj).call

But this seems to be really wordy and un-Rubyesque. Is there a better/cleaner/faster way of doing this? I'd prefer not modifying the underlying object to avoid unintentional consequences.

Essentially, I'm looking for javascript's apply or call.

Edit: My motivation for this is essentially encapsulation: I'd like to do this to objects in classes I didn't write, don't control, don't really need to understand in depth, and may react badly to having their own methods possibly replaced by a generic implementation. I realize that just including Enumerable will work in most cases, but when it goes wrong it's liable to be a pain to debug, so if there's a simple way to get mixin benefits without being so invasive, I'd prefer that.

Upvotes: 0

Views: 46

Answers (1)

Alex Peachey
Alex Peachey

Reputation: 4686

It sounds like for whatever reason you don't want to modify the class definition to include Enumerable but you can also of course just extend specific instances.

So you have indicated that obj implements each so you can just do this:

obj.extend(Enumerable).to_a

Ah, from your original question I thought the goal was to just not modify the class, so extending the instance was the most logical solution. However, it sounds like you don't want to modify the class or any instance.

I would do the following then:

obj.to_enum.to_a

Upvotes: 1

Related Questions