Saturn
Saturn

Reputation: 18149

How to override the constructor of a Ruby class that extends a Java class?

Have

class Object
  alias :old_initialize :initialize
  pause_warnings
  def initialize
    old_initialize
    print "BOOM"
  end
  resume_warnings
end

Then

class Foo < SomeJavaClass
  def initialize
    super()
  end
end

Why, when I create a Foo object, is it not printing?

pause_warnings and resume_warnings simply modify $VERBOSE

Upvotes: 3

Views: 424

Answers (2)

Max
Max

Reputation: 15955

What is your opinion on using a module?

module MyModule
  def self.included base
    class << base
      alias_method :old_new, :new

      define_method :new do |*args| # You can also use `def new(*args)` if you don't mind the scope gate
        pause_warnings
        old_new(*args).tap do |instance|
          print "BOOM"
          resume_warnings
        end
      end
    end
  end
end

The usage looks like this:

class Foo < SomeJavaClass
  include MyModule
end

A few small notes:

1) I was not able to test this on JRuby since I use Rubinius.

2) The behavior is slightly different. In your code, you pause warnings, define the initialize method, and then resume warnings. In my code, I pause warnings, create the object, and resume warnings. This means warnings will be pause/resumed once in your code (on class definition), and the warnings will be paused/resume many times in my code (on object creation). I wasn't sure what the correct behavior was here. If you want the same behavior, just move the pause/resume warnings above/below the define_method block (instead of inside it).

3) Your code allocates the memory for the object and then calls your initialize method. My code executes code before memory allocation occurs for the new object.

Upvotes: 2

Sanket
Sanket

Reputation: 490

I think you should try this,

as per your question you want to override the object class constructor, do like this

class Object
  def initialize
    super() # This will call old initialize method.
    print "BOOM"
  end
end

class Foo
  def initialize
    super()
  end
end

Foo.new()
#BOOM => #<Foo:0x9e66500>

Upvotes: 0

Related Questions