Question: Why do people use `Module.send(:prepend, …)`?

Question

Why do people use `Module.send(:prepend, …)`?

Answers 1
Added at 2017-01-03 09:01
Tags
Question

I'm learning how to use Module.prepend instead of alias_method_chain in my Ruby code, and I've noticed that some people use send to call it (example):

ActionView::TemplateRenderer.send(:prepend,
    ActionViewTemplateRendererWithCurrentTemplate)

While others call it directly (example):

ActionView::TemplateRenderer.prepend(ActionViewTemplateRendererWithCurrentTemplate)

And, although I haven't seen anyone use this style, I suspect from the documentation that you could even write this in the module you're prepending from:

module ActionViewTemplateRendererWithCurrentTemplate
    # Methods you're overriding go here

    prepend_features ActionView::TemplateRenderer
end

Is there some difference between these three styles? Is there a reason to favor one over the others?

Answers
nr: #1 dodano: 2017-01-03 10:01

Module#prepend was added to Ruby version 2.0.0.

It was originally added as a private method, with the intended use case being in the following format:

module Foo
  # ...
end

class Bar
  prepend Foo

  # ... The rest of the class definition ...
end

However, it soon became apparent that in many cases people wanted to prepend a module to a class without defining any other aspects of the class (in that section of code). Hence, the following pattern became common:

Bar.send(:prepend, Foo)

In Ruby version 2.1.0, this issue was addressed by making Module#prepend a public method - so you can now simply write this as:

Bar.prepend(Foo)

However, note that if you are writing a library that is required to support Ruby 2.0.0 (even though official support ended on 24th Feb 2016), then you must unfortunately stick to the old .send(:prepend, ...) approach.

Module#include (which has been in the Ruby language since its inception) was also a private method in version <= 2.0.0, and was made public in 2.1.0.

Source Show
◀ Wstecz