开发者

Dynamic Inheritance in Ruby

I'm trying to make a Ruby class that is very flexible as to it开发者_运维问答s type and hopefully can inherit properties from a number of other classes depending on the values its initialized with:

class Test
  def initialize(type,etc)
    case type
    when "stringio"
      inherit_from_stringio_with_data(etc)
    when "list"
      inherit_from_enumerable_with_data(etc)
    # and so on
    end
  end
end

Test.new("list").each do |item|
  p item
end

s = Test.new("stringio")
s.seek(3)
puts s.read(2)

I know of - or rather have read of - the power of the mixin, but as far as I can tell this isn't quite laid out correctly. Does anyone have any ideas, or am I trying something that's best achieved otherways (by having, say @content, that contains etc as a StringIO, Enumerable etc).

Thanks!


module Stringy
       def foo
           puts "I am a stringy"
       end
end

module Inty
       def bar
           puts "I am inty"
       end
end


class Test
      def initialize(mod_type)
          self.extend(mod_type)
      end
end


test = Test.new(Stringy)


There's no reason to pass a string representing a class name — you can just pass a class or instance of a class. Here's a version that takes an object and switches on its type.

class Test
  def initialize(obj)
    @content = obj
    forwarded_methods = case @content
      when StringIO then [:seek, :read]
      when Enumerable then [:each]
      else raise "Invalid type"
    end
    eigenclass = class<<self; self; end
    eigenclass.class_eval do
      extend Forwardable
      def_delegators :@content, *forwarded_methods
    end
  end
end

Test.new([1,2,3]).each do |item|
  p item
end

s = Test.new(some_stringio_object)
s.seek(3)
puts s.read(2)


Check DelegateClass and Forwardable, I think this is more the direction you need to go (universal facade containers). You don't need to have classes for them per s.e. since a class is just an object and not purely a syntactic construct.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜