代码之家  ›  专栏  ›  技术社区  ›  Kyle Decot

Ruby中的DelegateClass与类继承

  •  18
  • Kyle Decot  · 技术社区  · 10 年前

    请有人通过以下方式提供一些关于何时使用授权的见解: DelegateClass (例如:。 Seller < DelegateClass(Person) )以及何时使用类继承(例如。 Seller < Person )用红宝石做的?

    class Seller < DelegateClass(Person)
      def sales
         ...
      end 
    end 
    
    class Seller < Person 
      def sales
         ...
      end 
    end 
    

    当我在Github上查看Ruby on Rails源代码时,我发现了很多 uses of DelegateClass .

    2 回复  |  直到 10 年前
        1
  •  12
  •   coreyward    10 年前

    1) 您可以安全地委托给基元(例如String),但不能总是安全地继承它们

    如果你在 Hash String Fixnum ,使用更安全 DelegateClass (或其他授权人)。有关原因的更多信息, Steve Klabnik's cautioning 是一个很好的起点)。

    2) DelegateClass可以轻松地将更通用的对象转换为更具体的对象

    这样可以更容易地接受通用对象的实例,并使其以特定于您的实现的方式运行:

    class Message < DelegateClass(String)
      def print
        upcase
      end
    end
    
    # […]
    
    def log(message)
      message = Message.new(message) unless message.is_a?(Message)
    end
    

    3) 明白了: 子类需要委托类的实例作为 new

    这会使您要传递给库代码的子类变得复杂。例如,这是一种相当常见的做法,但它不能开箱即用 委托类 :

    class MyLogger < DelegateClass(ActiveSupport::Logger); end
    
    Foo::ThirdParty::Library.configure do |c|
      c.logger = MyLogger # no good
    end
    

    这不起作用,因为我们的库希望像大多数记录器一样工作,并在没有参数的情况下实例化。这可以通过定义 initialize 并创建的实例 ActiveSupport::Logger ,但在这种情况下可能不是正确的解决方案。

        2
  •  4
  •   quinn    10 年前

    Person Bear Tiger 继承自 Animal ,但一个实例 动物 有时不需要像 有时表现得像 。的后代的实例 动物 要么是其中之一,要么是另一个。