2012-08-25 76 views
0

我有一个名为CoordinatedModule,它提供了与距离相关的方法,以实现latitudelongitude方法的任何模型。如何要求包含模型的类实现某些方法?

module Coordinated 
    ... 
    def crow_flies_to(place) 
    raise ArgumentError, "place does not implement latitude and longitude" unless is_coordinated?(place) 
    Math.sqrt((latitude - place.latitude).abs**2 + (longitude - place.longitude).abs**2) 
    end 

    def is_coordinated?(place) 
    place.respond_to?(:latitude) && place.respond_to?(:longitude) 
    end 
    ... 
end 

我想测试加载的类时到被包括Coordinated类实现所需的方法。我怎么做?

回答

1

您可以使用运行时模块包括included钩:

module M 
    def self.included(klass) 
    raise "Must implement 'foo'" unless klass.instance_methods.include?(:foo) 
    end 
end 

class C; include M; end 
#=> RuntimeError 

class C 
    def foo; end 
    include M 
end 
#=> C 

其缺点是,列入必须发生在定义的方法之后,因为它们必须存在,当钩运行。

+0

完美答案。谢谢。 – barelyknown

+0

这也意味着你不能将这个mixin用于透明地将该功能委托给另一个对象而不是自己实现它的对象。当然,这在面向对象编程中是强大的技术。事实上,取决于你问谁,无法区分自己执行功能和将它委托给其他人是面向对象的*定义*。 IOW:这个解决方案使得不可能使用面向对象。 –

+0

@JörgWMittag哦,我同意并认为这样做首先是一个非常讨厌的想法。一个模块不应该关心一个方法是否被实现,直到它尝试使用它。这也会因为只有通过method_missing存在的方法而中断。 –

相关问题