Created
          October 29, 2012 11:33 
        
      - 
      
 - 
        
Save unixcharles/3973073 to your computer and use it in GitHub Desktop.  
    DelegateClass and "superclass mismatch for class" errors
  
        
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | require 'delegate' | |
| class Klass < DelegateClass(String) | |
| # ... | |
| end | |
| class Klass < DelegateClass(String) | |
| # Re-open the class | |
| end | |
| # => TypeError: superclass mismatch for class Klass | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | require 'delegate' | |
| DELEGATE_STRING = DelegateClass(String) unless defined?(DELEGATE_STRING) | |
| class Klass < DELEGATE_STRING | |
| # ... | |
| end | |
| class Klass < DELEGATE_STRING | |
| # Re-open the class | |
| end | 
  
    
      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
      Learn more about bidirectional Unicode characters
    
  
  
    
  | > require 'delegate' | |
| => true | |
| > DelegateClass(String).object_id == DelegateClass(String).object_id | |
| => false | 
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.
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
  
            
Thanks for posting this. Ran into this issue today.