Did anyone happen to take notes on Markus's module include technique (Like AS::Concern) from a few months ago?

3 views
Skip to first unread message

Jesse Cooke

unread,
Jun 8, 2011, 3:37:24 PM6/8/11
to pdx...@googlegroups.com
Or Markus, could you share it again?

--------------------------------------------
Jesse Cooke :: N-tier Engineer
jc00ke.com / @jc00ke

markus

unread,
Jun 8, 2011, 3:54:01 PM6/8/11
to pdx...@googlegroups.com
On Wed, 2011-06-08 at 12:37 -0700, Jesse Cooke wrote:
> Or Markus, could you share it again?

Was this what you're looking for (the one based on rcoder's lament on
twitter)?

-- Markus

class A
def foo
"okay!"
end
end

module B
def foo
"not " + super
end
end

module C
def foo
"really " + super
end
end

class X < A
include B
include C
end


class Object
def eigenclass
class << self; self; end
end
end

class Class
def wrap_methods &_
include Module.new &_
end
end

class Person
wrap_methods {
def hello
"Hello"
end
}
end

flanders = Person.new

p flanders.hello # => "Hello"

Person.wrap_methods {
def hello
"#{super}-diddly"
end
}
p flanders.hello

puts (x1 = X.new).foo

X.wrap_methods { def foo;"Who says it's #{super.gsub(/!/,'?')}";end }
X.wrap_methods { def foo;"#{super}\nPersonally, I think it's kind of
cool.";end }

puts X.new.foo
puts x1.foo

x2 = X.new
x2.eigenclass.wrap_methods { def foo;"Ha! #{super.length}"; end }

puts X.new.foo
puts x2.foo


Jesse Cooke

unread,
Jun 8, 2011, 3:58:54 PM6/8/11
to pdx...@googlegroups.com
Yes, that's the one, thanks!


--------------------------------------------
Jesse Cooke :: N-tier Engineer
jc00ke.com / @jc00ke




--
You received this message because you are subscribed to the Google Groups "pdxruby" group.
To post to this group, send email to pdx...@googlegroups.com.
To unsubscribe from this group, send email to pdxruby+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/pdxruby?hl=en.


Lennon Day-Reynolds

unread,
Jun 8, 2011, 4:17:01 PM6/8/11
to pdx...@googlegroups.com
On Wed, Jun 8, 2011 at 12:54 PM, markus <mar...@reality.com> wrote:

I have to admit, now that I understand this pattern, I find myself
being tempted to use it all over the place. Thankfully, I mostly
refrain from doing so, and when an instance sneaks by, my colleagues
catch in in code review.

It's seriously clever, in a way that I a) enjoy playing with, and b)
don't really like seeing in production code. (Don't even get me
started on method definitions in the eigenclass, or we'll be stuck in
this thread all day.)

--
Lennon Day-Reynolds <rco...@gmail.com>
http://rcoder.net/

markus

unread,
Jun 8, 2011, 5:05:56 PM6/8/11
to pdx...@googlegroups.com

> I have to admit, now that I understand this pattern, I find myself
> being tempted to use it all over the place. Thankfully, I mostly
> refrain from doing so, and when an instance sneaks by, my colleagues
> catch in in code review.
>
> It's seriously clever, in a way that I a) enjoy playing with, and b)
> don't really like seeing in production code. (Don't even get me
> started on method definitions in the eigenclass, or we'll be stuck in
> this thread all day.)

The funny thing is, it wasn't originally considered "seriously clever",
it was just the way ruby worked. The functionality was there
specifically to be used in this way and the community (much smaller at
the time, and largely native Japanese speakers) just accepted it as
such.

Then came the rails hordes and, assuming there wasn't a way to do this
already, they invented the myriad alias chain games which for most use
cases appear (to me) to be overly clever reinventions of a preexisting
wheel.

Alias chain games feel like (again, to me) like having variables called
a_1, a_2, a_3, etc. when what you really want is an array, or
product_name, product_quantity, product_price, etc. when you really want
a class. It's simulating a data structure (an array, a class or a
module) by playing with names.

So I guess it's all relative to what you're used to, or at least to what
you're expecting. :)

-- Markus


Anthony Cook

unread,
Jun 8, 2011, 5:28:18 PM6/8/11
to pdx...@googlegroups.com
Its just the way single inheritance with mixins works.
It cascades up the chain, thats explicitly the reason why Ruby uses mixins instead of multiple inheritance.
So you can define the execution chain and avoid the diamond inheritance problem.

:A

Anthony Cook

unread,
Jun 8, 2011, 5:35:50 PM6/8/11
to pdx...@googlegroups.com
In fact thats a really contrived example.

Look at it this way instead:

class A
def foo
'Really'
end
end

module B
def foo
super + ' just'
end
end

module C
def foo
super + ' fine.'
end
end

class X < A
include B
include C
end

X.new.foo
#=> "Really just fine."

:A

Lennon Day-Reynolds

unread,
Jun 8, 2011, 5:40:58 PM6/8/11
to pdx...@googlegroups.com
On Wed, Jun 8, 2011 at 2:28 PM, Anthony Cook <anthon...@bizbuilt.com> wrote:
> Its just the way single inheritance with mixins works.
> It cascades up the chain, thats explicitly the reason why Ruby uses mixins instead of multiple inheritance.
> So you can define the execution chain and avoid the diamond inheritance problem.

Don't get me wrong: the mechanism makes perfect sense given the
constraints of single-inheritance and the desire to inject additional
functionality via mixins.

In practice, it results in de facto multiple inheritance, with all the
power and problems that entails. Hence my presentation of it as a
"code smell" that has to solve a really critical problem to avoid
getting refactored out of the code. Like any inherited implementation,
it usually has a compositional alternative that, while potentially
more verbose, is also much more clear and less order-dependent.

Truthfully, I really, really love all these little corners and
low-level details of Ruby; it's a big part of what attracted me to the
language 10 years ago, and I will vigorously defend the existence of
such features in the language. That doesn't mean, however, that I want
to see them heavily leveraged in application code in a production
context.

Lennon Day-Reynolds

unread,
Jun 8, 2011, 5:44:03 PM6/8/11
to pdx...@googlegroups.com
On Wed, Jun 8, 2011 at 2:40 PM, Lennon Day-Reynolds <rco...@gmail.com> wrote:
> Truthfully, I really, really love all these little corners and
> low-level details of Ruby; it's a big part of what attracted me to the
> language 10 years ago, and I will vigorously defend the existence of
> such features in the language. That doesn't mean, however, that I want
> to see them heavily leveraged in application code in a production
> context.

tl;dr:

me: You kids get off my lawn with your eigenclasses and implicit
inheritance chain!
you: Look out, ol' Mr. @rcoder is getting grumpy again...

Anthony Cook

unread,
Jun 8, 2011, 5:50:16 PM6/8/11
to pdx...@googlegroups.com
Certainly it could be overused. If you're overriding a method many times I'd say thats definitely a problem.
It increases code complexity and makes tracing bugs much more difficult.

I'm pretty sure I've never used that pattern in practice, I've never had cause to. So maybe its something that should be avoided in favor of other alternatives.
The real truth of that matter is that if everything looks like a nail, you probably need more tools.

:A

markus

unread,
Jun 8, 2011, 6:03:52 PM6/8/11
to pdx...@googlegroups.com

> In practice, it results in de facto multiple inheritance, with all the
> power and problems that entails. Hence my presentation of it as a
> "code smell" that has to solve a really critical problem to avoid
> getting refactored out of the code. Like any inherited implementation,
> it usually has a compositional alternative that, while potentially
> more verbose, is also much more clear and less order-dependent.

To be fair, multiple inheritance in languages/styles that don't handle
it well. In Haskel you can derive Show, Eq, Ord, etc. till the cows
come home and no one raises an eyebrow.

> Truthfully, I really, really love all these little corners and
> low-level details of Ruby; it's a big part of what attracted me to the
> language 10 years ago, and I will vigorously defend the existence of
> such features in the language. That doesn't mean, however, that I want
> to see them heavily leveraged in application code in a production
> context.

So do you object to the unstructured forms (e.g. alias method chains)
just as strongly? :)

-- M

P.S. By the way, I don't know if I ever thanked you for the original
tweet which inspired the hangman that launched this thread, but I will
now: thank you. It's proved very productive for my purposes (getting
people to think more deeply about the semantics of ruby while having
fun).

Lennon Day-Reynolds

unread,
Jun 8, 2011, 6:29:32 PM6/8/11
to pdx...@googlegroups.com
On Wed, Jun 8, 2011 at 3:03 PM, markus <mar...@reality.com> wrote:
>
>> In practice, it results in de facto multiple inheritance, with all the
>> power and problems that entails. Hence my presentation of it as a
>> "code smell" that has to solve a really critical problem to avoid
>> getting refactored out of the code. Like any inherited implementation,
>> it usually has a compositional alternative that, while potentially
>> more verbose, is also much more clear and less order-dependent.
>
> To be fair, multiple inheritance in languages/styles that don't handle
> it well.  In Haskel you can derive Show, Eq, Ord, etc. till the cows
> come home and no one raises an eyebrow.

True, though Show, Eq, Ord, et. al. don't actually stomp on each
other's method namespaces.

>> Truthfully, I really, really love all these little corners and
>> low-level details of Ruby; it's a big part of what attracted me to the
>> language 10 years ago, and I will vigorously defend the existence of
>> such features in the language. That doesn't mean, however, that I want
>> to see them heavily leveraged in application code in a production
>> context.
>
> So do you object to the unstructured forms (e.g. alias method chains)
> just as strongly?  :)

More so. Core language features are at least guaranteed to be
available in any runtime context. I hate seeing ActiveSupport-isms
sneak into non-Rails code.

> P.S. By the way, I don't know if I ever thanked you for the original
> tweet which inspired the hangman that launched this thread, but I will
> now: thank you.  It's proved very productive for my purposes (getting
> people to think more deeply about the semantics of ruby while having
> fun).

You're quite welcome. I've always been a fan of the hangman puzzles.

Reply all
Reply to author
Forward
0 new messages