How to get an inherited callback in ruby ​​that starts after defining a child class, not earlier

Possible duplicate:
ruby: can I have something like an inherited class # that runs only after the class is defined?

class A
  def self.inherited(child)
    puts "XXX"
  end
end

class B < A
  puts "YYY"
end

displays

XXX
YYY

I would prefer

YYY
XXX

if I could somehow figure it out.

+5
source share
3 answers

You can trace until you find the end of the class definition. I did this in a method that I called after_inherited:

class Class
  def after_inherited child = nil, &blk
    line_class = nil
    set_trace_func(lambda do |event, file, line, id, binding, classname|
      unless line_class
        # save the line of the inherited class entry
        line_class = line if event == 'class'
      else
        # check the end of inherited class
        if line == line_class && event == 'end'
          # if so, turn off the trace and call the block
          set_trace_func nil
          blk.call child
        end
      end
    end)
  end
end

# testing...

class A
  def self.inherited(child)
    after_inherited do
      puts "XXX"
    end
  end
end

class B < A
  puts "YYY"
  # .... code here can include class << self, etc.
end

Conclusion:

YYY
XXX
+15
source

It's impossible. Consider this: when should a class definition be defined in Ruby?

self.inherited finalize! .

# A silly, contrived example

class A
  def self.author(person)
    @@authors ||= Array.new
    @@authors << person
  end

  def self.finalize!
    @@authors.map! { |a| Author[a] }
  end
end

class B < A
  author "Jason Harris"
  author "George Duncan"

  finalize!
end

, -:

class A
  def self.define_authors(&blk)
    yield
    # (...finalize here)
  end
  ...
end

class B < A
  define_authors {
    author "Jason Harris"
    author "George Duncan"
  }
end

... , , .

+1

AFAIK.

:

class A
  @@my_lambda = nil
  def self.inherited(child)
    @@my_lambda = lambda { puts "XXX" }
  end

  def self.after_inherited
    @@my_lambda.yield
  end
end

class B < A
  puts "YYY"
  # other definitions
  self.superclass.after_inherited
end

, :

YYY
XXX

, , B after_interited() A. , , , , .

0

All Articles