Create a gist now

Instantly share code, notes, and snippets.

#include and #extend have same effect on instances as inheritance

Let's say we have this

module A; end
module B; end
class C; end
class D < C; end

Then we modify instance

d = D.new
D.send(:include, A)
d.extend(B)
d_meta = class << d; self; end

Lets see what we got (method dispatch lookup table)

d.class.ancestors
=> [D, A, C, Object, Kernel, BasicObject]

d_meta.ancestors
=> [B, D, A, C, Object, Kernel, BasicObject]

So it's all up to how and what structure you see

and to me, benefits of composition over inheritance is that it doesn't modify object dispatch hierarchy.

PS: pls comment here.

@mikepack
mikepack commented Feb 1, 2012

Interesting, thanks for this gist.

Does d_meta contain B as an ancestor because it's including d's singleton class in the lookup hierarchy?

@gmarik
Owner
gmarik commented Feb 1, 2012

That's correct.
Inheritance, include and extend use same technique: modifying the lookup hierarchy.
The difference between them is the location where the features are injected/placed(precedence) in the hierarchy.
Smth like this: extend(B) > class(D) > include(A) > inherit(C).

But i'm not a ruby meta-programming guru, so take above critically )

@mikepack
mikepack commented Feb 7, 2012

I'm curious why you're drawn to these fallacies around extend/include at runtime. Have you been bitten by this before in the past? I often don't inherit from objects (like d_meta), but then maybe I don't do enough obscure programming :)

@gmarik
Owner
gmarik commented Feb 8, 2012

Well, the statement was "it's a good hack, but bad practice".
Works fine on small scopes, but once grows it becomes harder to read thus understand the code, given this as a normal practice.
Debugging is hard because it's not quite obvious why it's doing one thing instead of another and that's only because at some point of call stack an object got extended with a module.

Don't get me wrong, it works. But at certain point it's like "magic" )

I don't do enough obscure programming

well, that's how you start! ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment