So I actually ended up with this solution. I'm still open for suggestions.
class ::Object
def object(name, klass = Object, &block)
instance = klass.allocate
if instance.method(:initialize).owner == BasicObject
instance.instance_exec(&block) if block_given?
else
raise "No block given." unless block_given?
instance.instance_exec do
def initialize(*args)
@__initialized = true
super
end
end
instance.instance_exec(&block)
instance.instance_exec do
raise "Instance of #{klass} needs to be initialized." unless @__initialized
remove_instance_variable :@__initialized
end
end
(self.is_a?(Module) ? self : self.class).const_set(name, instance)
end
end
I could use it like
object :Hey, SomeClassWithInitialize do
puts "Perhaps sometimes I'd be doing some things first before initializing."
initialize
puts "And other things after initializing."
def hey!
puts "Hey!"
end
end
Hey.hey!
Update: Turns out that there really is no function in Ruby that declares a flag that initialize
is called. All calls from rb_obj_call_init
to rb_obj_dummy
does nothing significant to this.
̶I̶ ̶m̶a̶y̶ ̶j̶u̶s̶t̶ ̶c̶o̶n̶s̶i̶d̶e̶r̶ ̶u̶s̶i̶n̶g̶ ̶s̶i̶m̶p̶l̶e̶ ̶s̶i̶n̶g̶l̶e̶t̶o̶n̶s̶ ̶f̶o̶r̶ ̶i̶n̶s̶t̶a̶n̶c̶e̶s̶ ̶t̶h̶a̶t̶ ̶d̶o̶e̶s̶n̶'̶t̶ ̶i̶n̶h̶e̶r̶i̶t̶ ̶a̶n̶y̶t̶h̶i̶n̶g̶,̶ ̶a̶n̶d̶ ̶̶S̶i̶n̶g̶l̶e̶t̶o̶n̶#̶i̶n̶s̶t̶a̶n̶c̶e̶
̶ ̶f̶o̶r̶ ̶a̶n̶y̶t̶h̶i̶n̶g̶ ̶t̶h̶a̶t̶ ̶d̶o̶e̶s̶ ̶o̶v̶e̶r̶ ̶t̶h̶i̶s̶ ̶m̶e̶t̶h̶o̶d̶ ̶b̶u̶t̶ ̶i̶t̶ ̶w̶o̶u̶l̶d̶ ̶o̶n̶l̶y̶ ̶b̶e̶ ̶c̶o̶n̶c̶l̶u̶d̶e̶d̶ ̶w̶h̶e̶n̶ ̶I̶ ̶a̶c̶t̶u̶a̶l̶l̶y̶ ̶u̶s̶e̶ ̶o̶n̶e̶.̶ Classes declared with Singleton does not inherit. I forgot.
Using an alias and an extra method was actually not needed.