2 votes

Héritage dynamique en Ruby

J'essaie de créer une classe Ruby qui soit très flexible quant à son type et qui, je l'espère, puisse hériter des propriétés d'un certain nombre d'autres classes en fonction des valeurs avec lesquelles elle est initialisée :

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)

Je connais - ou plutôt j'ai lu - la puissance du mixin, mais pour autant que je puisse dire, ce n'est pas tout à fait exposé correctement. Est-ce que quelqu'un a une idée, ou est-ce que j'essaie quelque chose qui est mieux réalisé d'une autre manière (en ayant, disons @content qui contient etc en tant que StringIO , Enumerable etc).

Gracias.

3voto

cgr Points 542
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)

2voto

Chuck Points 138930

Il n'y a aucune raison de passer une chaîne représentant un nom de classe - vous pouvez simplement passer une classe ou une instance de classe. Voici une version qui prend un objet et bascule sur son 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)

1voto

Julik Points 3226

Vérifiez DelegateClass et Forwardable, je pense que c'est plutôt la direction que vous devez prendre (conteneurs de façade universels). Vous n'avez pas besoin d'avoir des classes pour eux par exemple, puisqu'une classe est juste un objet et non une construction purement syntaxique.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X