Skip to content

Instantly share code, notes, and snippets.

@unixcharles
Created October 29, 2012 11:33
Show Gist options
  • Save unixcharles/3973073 to your computer and use it in GitHub Desktop.
Save unixcharles/3973073 to your computer and use it in GitHub Desktop.
DelegateClass and "superclass mismatch for class" errors
require 'delegate'
class Klass < DelegateClass(String)
# ...
end
class Klass < DelegateClass(String)
# Re-open the class
end
# => TypeError: superclass mismatch for class Klass
require 'delegate'
DELEGATE_STRING = DelegateClass(String) unless defined?(DELEGATE_STRING)
class Klass < DELEGATE_STRING
# ...
end
class Klass < DELEGATE_STRING
# Re-open the class
end
> require 'delegate'
=> true
> DelegateClass(String).object_id == DelegateClass(String).object_id
=> false
@dtuite
Copy link

dtuite commented Jul 3, 2014

Thanks for posting this. Ran into this issue today.

@probablykabari
Copy link

Just to note why this happens, DelegateClass(SomeClass) is really doing Class.new(SomeClass) and assigning it as the superclass. That's why it's a different object and not the same superclass each time.

@cormacc
Copy link

cormacc commented Nov 9, 2017

Thanks for the explanation of the issue -- had me scratching my head. I was running into this when reloading source files from a pry session to pick up changes. Chose to do something similar in a module, to eliminate the ...unless defined? boilerplate per class. It may well be bad ruby - I'm a dabbler.

# This module wraps DelegateClass to eliminate the error on reload, which is an aggravation during development
#
# To use it, just replace any incidence of
#
#   class MyClass < DelegateClass(SomeOtherClass)
#
# with
#
#   class MyClass < NMD::ExplicitDelegator.to(SomeOtherClass)

module NMD
  module ExplicitDelegator
    class << self
      attr_accessor :class_cache
      def to superclass
        superclass_id = superclass.to_s
        @class_cache = {} if @class_cache.nil?
        @class_cache[superclass_id] = DelegateClass(superclass) if @class_cache[superclass_id].nil?
        @class_cache[superclass_id]
      end
    end
  end
end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment