确保Ruby中的接口合规性?

时间:2017-06-14 10:45:24

标签: ruby interface

我非常喜欢Ruby,但我对如何实现接口感到困惑。在下面显示的示例中,类A在对象上调用方法get_data,该对象作为构造函数参数传入。确保obj具有正确类型并实现方法get_data的最佳做法是什么?我见过的代码只是"指定了所需的接口"在类的initialize方法的RDoc中:"参数必须包含模块Bar","参数必须是Blah"或"参数必须有方法' get_data'"。是否有更好的程序化方式?

class A

   def initialize(obj)
     @obj = obj
   end

   def foo
     # Do something with @obj
     var = @obj.get_data
     ...
   end

end

2 个答案:

答案 0 :(得分:1)

我认为您所看到的是依赖注入,而不是在您的方法SomeClass.new.get_data

中进行硬编码foo

A类具有信任级别初始化A的对象应该传递参数,这是SomeClass的对象,就像这样。

object_a = A.new(SomeClass.new)。

因此,如果您想明确检查@obj是否可以回复邮件get_data,您可以使用ruby' s respond_to?(:method_name)

所以你的代码变成了这个

   def foo
     # Do something with @obj
     if @obj.respond_to?(:get_data)
       var = @obj.get_data
     end
     ...
   end

答案 1 :(得分:-1)

Ruby是一种动态类型的语言,它也是鸭子类型,当你决定使用鸭子打字功能时,你应该在文档中提及它并调用它,如果它不存在它会崩溃,仔细想想,假装你可以检查fsync()是否存在(你可以在后面看到),你想做什么?

您要退回get_data吗?如果nil应该返回一个值,您可以返回foo,但如果nil意图返回任何内容(语义无效),那么您将为用户带来NoSuchMethodError for nil:NilClass的风险foo不是你的选择,你想nil出错吗?很可能你想检查raise存在的原因是为了防止类型错误,但是现在你又引发了一个错误,也许你想提出一个特定的错误,但老实说get_data在我看来是特定的。

在我的脑海里,我会告诉你如何检查它,有很多方法,一个非常简单的方法:

NoSuchMethodError : method get_data missing in someObject:SomeClass

可能更好的方法是使用上述方式检查def foo begin var = @obj.get_data rescue NoMethodError // handle the case where get_data does not exist end end objget_data是否initialize

def initialize(obj)
    if(!obj.respond_to? :get_data)
       //handle the case where get_data is not defined
    end
end

最后一个代码的问题是,您检查的所有内容都是obj get_data,如果您想检查是否可以,请不要检查是否有正确的签名:< / p>

def initialize(obj)
  unless(!obj.respond_to? :get_data) 
     params = obj.method(:get_data).parameters
     //if get_data for example takes x,y then params will be `[[:req,:x],[:req,:y]]`         
  end
end

当然,您无法检查get_data是否接受特定类型,因为ruby是动态类型的。

如果您还想检查方法的存在和参数后检查方法的返回类型,可以调用它,因为它是安全的并检查返回类型如下:

a=obj.get_data
if(a.is_a? SomeClass)
   //good
end

如果你想检查get_data什么都不返回(语义上是无效的方法),那么ruby返回nil类似于void,但是返回一个值也是如此,所以你不能检查它