Class#inherited, class definition and industry

Hi there.

Am I correct in thinking that the #inherited method of the parent class
is called before the body of the class is evaluated?

If so, is there a more sensible way of working around this, than
something like the following?

sample.rb (522 Bytes)

···


Ceri Storey cez@necrofish.org.uk

Hi,

Am I correct in thinking that the #inherited method of the parent class
is called before the body of the class is evaluated?

Yes. The end of definition cannot be determined in Ruby.

If so, is there a more sensible way of working around this, than
something like the following?

I thought of similar one formerly, and still haven’t get better
one.

Well, how about #singleton_method_added, if you use particular
singleton method as the key?

But note that Module#name is pre-defined method.

class Builder
@@registry = {}
class << self
def singleton_method_added(name)
@@registry[send(name)] = self if name == :name
super
end

  def lookup(name)
    @@registry.fetch(name) do
      raise ArgumentError, "No such Class"
    end
  end

  def create(name, *args)
    lookup(name).new(*args)
  end
end

end

class Moogle < Builder
def self.name
“moogle”
end
end

Builder.create(“moogle”)

Or, if names are always class names in lower case, you can use
the names even in #inherited.

class Builder
@registry = {}
class << self
def inherited(c)
@registry[c.name.downcase] = c
super
end

  def lookup(name)
    @registry.fetch(name) do
      raise ArgumentError, "No such Class"
    end
  end

end

You can define Builder.name as returning lower case name and
use it too.

class Builder
@registry = {}
class << self
def name
super.downcase
end
def inherited(c)
@registry[c.name] = c
super
end
end
end

And another one, with http://nokada.jin.gr.jp/ruby/factory.rb

require ‘factory’

class Builder
extend Factory
end

class Moogle < Builder
factory do |name, *args|
new(*args) if /\Amoogle\z/ =~ name
end
end

p Builder.create(“moogle”)

···

At Tue, 25 Nov 2003 23:26:58 +0900, Ceri Storey wrote:


Nobu Nakada