dubace
dubace

Reputation: 1621

Reinitialize a ruby Class

How i can solve it ?

class Person
end

class Person < ActiveRecord::Base
end

TypeError: superclass mismatch for class Person.


I want to reinitialize a class.

Upvotes: 1

Views: 1049

Answers (4)

Cezar
Cezar

Reputation: 56362

Once you've created a class in ruby, you can't alter its superclass by reopening it. That's why you're getting the TypeError: superclass mismatch for class Person. error.

Other answers have provided alternatives, but it is important to note that none of them modify the existing Person class, but actually create a new class and reassigns the old Person constant to the new class, under the limitations already stated by @user1158559 in his answer.

Upvotes: 5

SwiftMango
SwiftMango

Reputation: 15294

It might not be the answer you look for, but its a way to undefine a class or a constant so you can redefine it, but it will lose all the original methods:

Object.send(:remove_const, :Person) 

Upvotes: 1

user1158559
user1158559

Reputation: 1954

You can (sort of) do this.

# initial definition
class Person
end

# new definition
class OverridePerson < ActiveRecord::Base
end

Person = OverridePerson
  • Please see comment by @Andrew Marshall. You can undefine Person, then define it without creating dummy class OverridePerson

Similarities to what you want to do:

  • Person will refer to the new class

Differences to what you want to do:

  • Existing instances will not change their class
  • Class methods and variables will be clobbered
  • Person.name will be OverridePerson, but you can override that to be "Person"

Your use cases might be:

  • redefine Person, duck-typing it to fool a library or an application. IMO this is perfectly legit for testing purposes, though ActiveRecord::Base will be a hard one to duck-type. I recommend using FakeAR or RSpec mocks, or stubs on the original class

  • You want to make a class called Person, but it is already defined. In this case I recommend namespacing within a module.

Upvotes: 2

James Lim
James Lim

Reputation: 13054

Just make sure you use the same class signature every time.

class Person < ActiveRecord::Base
  def x
  end
end


class Person < ActiveRecord::Base
  def y
  end
end

Upvotes: 2

Related Questions