Search code examples
rubyopen-closed-principle

Is it possible in Ruby to redefine a initialize method?


I have a third-party code that's like this:

class Foo
  def initialize
    @hello = "world"
  end

  def msg
    @hello
  end
end

Then, I added a new file foo_redefinition.rb with these contents

class Foo
  def initialize
    @hello = "welt"
  end
end

Then, another third party code calls a method in my main class, and in the file of my main class I do require_relative 'foo_redefinition'. However, when the third party code (after calling my method, thus reading my main file, which requires the redefinition) calls Foo.msg, it returns "world", not "welt".

Also, when I do

require_relative 'foo_redefinition'

# ... lots of code

Foo::new.msg #=> world (instead of welt)

My questions are:

  1. Is it possible to redefine an initialize method?
  2. If so, what I am doing wrong here?

Solution

  • I'm afraid that Foo is a lazily autoloaded class, and you are "redefining" initialize before Foo is loaded.

    Try this

    Foo.class_eval do
      def initialize
        @hello = "welt"
      end
    end
    

    This forces Foo to be loaded before redefining anything.