pyt*_*iku 23 ruby oop duck-typing
由于ruby中没有类型,Ruby程序员如何确保函数接收正确的参数?现在,我正在重复if object.kind_of/ instance_of语句检查并在任何地方引发运行时错误,这很难看.必须有更好的方法来做到这一点.
saw*_*awa 21
我个人的方式,我不确定它是否一般是推荐的方式,是在发生错误时进行类型检查并进行其他验证.我把类型检查程序放在救援区.这样,我可以在给出正确的参数时避免性能损失,但在发生错误时仍然会返回正确的错误消息.
def foo arg1, arg2, arg3
...
main_routine
...
rescue
## check for type and other validations
raise "Expecting an array: #{arg1.inspect}" unless arg1.kind_of?(Array)
raise "The first argument must be of length 2: #{arg1.inspect}" unless arg1.length == 2
raise "Expecting a string: #{arg2.inspect}" unless arg2.kind_of?(String)
raise "The second argument must not be empty" if arg2.empty?
...
raise "This is `foo''s bug. Something unexpected happened: #{$!.message}"
end
Run Code Online (Sandbox Code Playgroud)
假设,在假设这是一个数组时main_routine使用该方法.如果事实证明它是其他东西,没有定义,那么裸错误信息将是类似的,从方法的用户的角度来看,可能没有帮助.在这种情况下,原始错误消息将被消息替换,这更有帮助.eacharg1arg1eachmethod each not defined on ...fooExpecting an array: ...
小智 18
当然,Ruby是动态类型的.
因此,方法文档确定类型合同; 类型信息从正式类型系统移动到方法文档中的[非正式类型规范].我混合了诸如"像数组一样的行为"的普遍性和诸如"是一个字符串"之类的细节.调用者应该只期望使用所述类型.
如果来电者违反了这个合同,那么任何事情都可能发生.该方法不用担心:它使用不正确.
鉴于上述情况,我避免检查特定类型,并避免尝试使用此类行为创建重载.
单元测试有助于确保合同适用于预期数据.
如果某个方法有理由存在,则会调用它.
如果编写合理的测试,将调用所有内容.
如果调用每个方法,那么每个方法都将进行类型检查.
不要浪费时间进行可能不必要地约束呼叫者的类型检查,并且无论如何都只会复制运行时检查.花那个时间写测试.