Mixin for Mixins

Going through some old code snippets and came across this clever bit.
Back
then I was planning to use this for Facets, before I finally determined
that using mixins wasn’t actually the best approach for a core
extensions
library.

module Extension
def self.included(base)
name = base.name.split(’::’).last
core = eval("::#{name}")
core.send(:include, base)
end
end

Example:

module Facets
  module String
    include Extension

    def drippy
      puts "Drippy #{self}"
    end
  end
end

"Hello".drippy

Just thought I’d share.

On Sun, Dec 25, 2011 at 10:48 PM, Intransition [email protected]
wrote:

end
    end
  end
end

"Hello".drippy

Just thought I’d share.

Why do you invoke the included method by including the Extension into
Facets::String? I see this all over the place (esp in Rails) but don’t
get
why. It’s just an ultra fancy way to invoke a method, but it pollutes
String’s ancestry and makes it nonobvious what’s happening. This code
doesn’t also extend in the included hook, but I see that a lot, too
(e.g.
https://github.com/rails/rails/blob/master/activerecord/lib/active_record/model.rb#L17
).

How about something like this as an alternative:

With included hook, pollutes string

module CoreExtension
def self.included(base)
name = base.name.split(‘::’).last
core = Object.const_get name
core.send(:include, base)
end
end

module Facets
module String
include CoreExtension

def drippy
  "Drippy #{self}"
end

end
end

“Hello”.drippy # => “Drippy Hello”
String.ancestors.include? CoreExtension # => true

Same functionality, but more clear and doesn’t add CoreExtension to

ancestry
module CoreExtension
def self.<<(base)
name = base.name.split(‘::’).last
core = Object.const_get name
core.send(:include, base)
end
end

module Facets
module String
CoreExtension << self

def drippy
  "Drippy #{self}"
end

end
end

“Hello”.drippy # => “Drippy Hello”
String.ancestors.include? CoreExtension # => false

On Monday, December 26, 2011 2:33:02 AM UTC-5, Josh C. wrote:

Why do you invoke the included method by including the Extension into
Facets::String? I see this all over the place (esp in Rails) but don’t get
why. It’s just an ultra fancy way to invoke a method, but it pollutes
String’s ancestry and makes it nonobvious what’s happening. This code
doesn’t also extend in the included hook, but I see that a lot, too (e.g.

https://github.com/rails/rails/blob/master/activerecord/lib/active_record/model.rb#L17

).

Fair point. You might want to pollute String with the CoreExtension
mixin.
OTOH, it makes it easy to identify that it was extended as such, e.g.

String.ancestors
=> [String, CoreExtension, Comparable, Kernel, BasicObject]

And since there are no instance methods in it I don’t think it hurts
anything.

How about something like this as an alternative:

Actually, if we used #append_features instead of #include, we could
prevent
the inclusion, but still use include to apply the extended features,

Oops, typo…

“Fair point. You might NOT want to…”