Module: Metamorphosis::RedefInit

Defined in:
lib/metamorphosis/core.rb

Overview

This module is responsible for extending forthcoming class instances with the new behavior defined by relevant spell(s). It's the responsability of the spells to call +super+ so as to fallback on original behavior: this module only has the auto-hooks up and runing.

In order to have instances existing prior to the plugin activation, one should pass the +:retroactive+ option to #activate.

Instance Method Summary collapse

Instance Method Details

#new(*args, &block) ⇒ Object

Redefine initialize/new so as to call extend [spells] on new instances. This allows for per-instance behavior redefinitions.



301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
# File 'lib/metamorphosis/core.rb', line 301

def new *args, &block
  o = super

  # notes: self is a const like Receiver::Some::Module,
  # spell_module is a const like Receiver::Spells::ASpell

  # FIXME: le bug: comme Loudness a été enregistré comme spell pour Project::Foo::Speaker,
  # la ligne 42 de test.rb arrive ici, et 299 essaye d'étendre un module InstanceMethods
  # qui n'existe pas pour Loudness. Il faut donc différencier les spells liés aux
  # InstanceMethods de ceux liés aux ClassMethods des autres dans @@redefinable.
  # C'est peut-être le moment de passer RubyTree? ou équivalent plus souple? OpenStruct?

  # FIXME: hashes don't keep insert order in Ruby 1.8 so it's not a good structure
  # to hold the spells references. Better use a tree with chained spell, spells as
  # tree leaves, and hierarchy for free.
  Metamorphosis.redefinable[self].each do |spell, modes|
    if modes.include? :instance_methods
      o.extend(spell.constant(self.name.split("::")[1..-1].join("::")).constant("InstanceMethods"))
    end
  end unless Metamorphosis.redefinable[self].empty?

  o
end