Hi!

I tried to play with superclass chain and here is what I've
discovered:

The first example, @superclass is changed and method is being found
correctly:

https://gist.github.com/888224

# Step 1. Setting up environment

class Government
  def power
    "belongs to government"
  end
end

module People
  def power
    "belogs to people"
  end

  Government.__send__ :include, self
end

government = Government.new


# Step 2. Swapping ancestors by re-setting @superclass

included_module = Government.instance_eval { @superclass }

government.metaclass.instance_eval { @superclass = included_module }
included_module.instance_eval { @superclass = Government }
Government.instance_eval { @superclass = Object }


# Step 3. Testing

puts government.metaclass.superclass_chain.inspect
# => [#<IncludedModule People>, Government, Object, #<IncludedModule
Kernel>] <-------- cool, prepended module is before Class
puts government.power
# =>  belongs to people  <--------- this is definitely right


The second example. Module#direct_superclass is changed.
Module#superclass_chain gives correct result, but wrong method is
being called.

https://gist.github.com/888225

module Rubinius
  class PrependedModule < IncludedModule
    attr_reader :module

    def initialize(mod, superclass)
      @module = mod
      @superclass = superclass
      super(mod)
    end

    def inspect
      "#<PrependedModule #{@module.to_s}>"
    end
  end
end

class Module
  attr_reader :prepended_module # for the sake of simplicity let's
take just one for now

  def prepend(mod)
    @prepended_module = Rubinius::PrependedModule.new(mod, self)
  end

  def direct_superclass
    if @superclass && @superclass.prepended_module &&
@superclass.prepended_module != self
      @superclass.prepended_module
    else
      @superclass
    end
  end
end


# -----------------------------------------

class Government
  def power
    "belongs to government"
  end
end

module People
  def power
    "belogs to people"
  end

  Government.prepend self
end


puts Government.new.metaclass.superclass_chain.inspect
# => [#<PrependedModule People>, Government, Object, #<IncludedModule
Kernel>]      <----- looks good, but...
puts Government.new.power
# => belongs to government              <---- ...is this right? ;)



So, I actually have two questions:
1) Is it a bug?
2) If it has been done intentionally, then  is there better way
manipulate superclass chain?

Thanks,
Daniel Vartanov.

-- 
--- !ruby/object:MailingList
name: rubinius-dev
view: http://groups.google.com/group/rubinius-dev?hl=en
post: [email protected]
unsubscribe: [email protected]

Reply via email to