Skip to content


alias_method alters visibility #1923

ngollan opened this Issue · 4 comments

2 participants


(edit: probably works not just with #initialize, so I changed the subject a few minutes after creation…)

When using alias_method to chain #initialize, the receiving class gains a public #initialize. This can lead to weird behaviour in code that makes heavy use of chaining and undefines methods based on visibility.

One affected codebase is Capistrano.

Reproduce with:

module Publicize
  def self.included(base)
    puts "Before: do we have #initialize? #{base.instance_methods.include?(:initialize) ? 'Yes' : 'No'}"
    puts "        ... private? #{base.private_methods.include?(:initialize) ? 'Yes' : 'No'}"

    base.send :alias_method, :old_initialize, :initialize
    base.send :alias_method, :initialize, :outer_initialize

    puts "After: do we have #initialize? #{base.instance_methods.include?(:initialize) ? 'Yes' : 'No'}"
    puts "       ... private? #{base.private_methods.include?(:initialize) ? 'Yes' : 'No'}"

  def outer_initialize(*args)

class ThatSimple
  include Publicize

On MRI 1.9.3, that yields:

Before: do we have #initialize? No
        ... private? Yes
After: do we have #initialize? No
       ... private? Yes

while on RBX master, I get:

Before: do we have #initialize? No
        ... private? Yes
After: do we have #initialize? Yes
       ... private? Yes

Note that RBX now shows #initialize as both public and private.


After correcting the misuse of private_methods which of course was looking at the class, things look like that:

So only the initialize method appears to be affected.


dbussink and I did some further digging, and it looks like a difference between 1.8 and 1.9 MRI.

MRI 1.8 has the same behaviour as rbx: Aliasing a method to the constructor results in a public #initialize method; however, in MRI 1.9, the constructor remains private through aliasing.


So to clarify:

We're missing a spec for 1.9 mode that says using alias_method :initialize, :foo, where #foo is a public method, should not make #initialize a public method, as well as the implementation to make that pass.

That is, running under rbx in 1.9 mode should print true, true, like MRI 1.9.3.

Is that correct?


Yes, that sounds good as far as I can remember.

@dbussink dbussink closed this in #2523
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.