Dmitry Polushkin
Dmitry Polushkin

Reputation: 3393

Get name of anonymous class while inherited process

Is there are any possibility to get name of the anonymous class in the inherited, and not raise "fail A"? Should be made through Class object creation (no eval or similar).

class A
  def self.inherited(base)
    raise 'fail A' unless base.name
  end
end

B = Class.new(A)
# or
Object.const_set :B, Class.new(A)

The code above doesn't work, because anonymous class isn't yet initialized so it cannot be set to a specific constant.

Upvotes: 1

Views: 264

Answers (2)

mdesantis
mdesantis

Reputation: 8507

What about something like:

class Superclass
  def self.inherited(base)
    raise 'Invalid class name' unless @forced_anonymous_subclass_name == :A
  end
  def self.forced_anonymous_subclass_name
    @forced_anonymous_subclass_name
  end
  def self.with_forced_anonymous_subclass_name(class_name)
    @forced_anonymous_subclass_name = class_name
    yield
  ensure
    @forced_anonymous_subclass_name = nil
  end
end

sc = Superclass

sc.with_forced_anonymous_subclass_name(:A) do
  Object.const_set sc.forced_anonymous_subclass_name, Class.new(sc)
end #=> A

sc.with_forced_anonymous_subclass_name(:B) do
  Object.const_set sc.forced_anonymous_subclass_name, Class.new(sc)
end #=> RuntimeError

Feel free to ask if unclear/improvements/etc.

Upvotes: 1

Andrew Marshall
Andrew Marshall

Reputation: 96914

No.

An anonymous class doesn’t have a name until it’s been assigned to a constant (e.g. (B = Class.new).name #=> "B"). Since assignment does not happen until after the class instance has been created (during which hooks—including inherited—are called), there’s no way you can get the name until afterwards.

Upvotes: 5

Related Questions