Ruby 干涸的论证检验
有一个方法通常是用命名参数调用的,它如下所示Ruby 干涸的论证检验,ruby,Ruby,有一个方法通常是用命名参数调用的,它如下所示 def foo(x = nil, y = nil) fail ArgumentError, "x must be present" unless x fail ArgumentError, "y must be present" unless y # do stuff with x and y end 我想改写成这样 def foo(x = nil, y = nil) required_arguments :x, :y # do
def foo(x = nil, y = nil)
fail ArgumentError, "x must be present" unless x
fail ArgumentError, "y must be present" unless y
# do stuff with x and y
end
我想改写成这样
def foo(x = nil, y = nil)
required_arguments :x, :y
# do stuff with x and y
end
或
我曾尝试使用别名\u方法\u链
实现第二种方法,但问题是\u方法\u方法
是在我的实用程序模块的上下文中评估的,因此我无法访问需要检查的方法的参数。有什么想法吗?这个,但它们确实有用。我已将它们合并到YSupport
中。在命令行中键入gem install y_support
,并按如下方式使用它
require 'y_support/typing'
def foo x=nil, y=nil
x.aT; y.aT
# do stuff with x and y
end
助记符:在aT
中,a
表示“断言”,而T
表示TypeError
–如果断言失败,则引发TypeError
。如果调用#aT
方法时没有参数,那么它只是强制要求接收方必须是真实的。如果提供了块,则可以写入任何断言。例如,以下调用强制接收器可被3整除:
6.aT { |n| n % 3 == 0 } #=> 6
7.aT { |n| n % 3 == 0 } #=> TypeError: 7:fixnum fails its check!
在检查方法参数时,ArgumentError
适用于参数数量错误和类似问题的情况。当参数类型错误时,我倾向于提出TypeError
。可以使用两个字符串参数自定义#aT
方法的错误消息。第一个描述接收者,第二个描述块断言。例如:
7.aT "number of apples", "be divisible by three" do |n| n % 3 == 0 end
#=> TypeError: Number of apples fails to be divisible by three!
#aT
方法如果通过,将返回其接收者,因此可以链接断言:
81.aT( "no. of apples", "divisible by 3 ) { |n|
n % 3 == 0
}.aT( "no. of apples", "be a square" ) { |n|
root = n ** 0.5; root == root.floor
} ** 0.5 #=> 9.0
YSupport
中提供了其他更专业的运行时断言,例如:
[ 1, 2, 3 ].aT_kind_of Enumerable #=> [ 1, 2, 3 ]
:foobar.aT_respond_to :each
#=> TypeError: Foobar:symbol does not respond to method 'each'!
:foobar.aT_respond_to :each, "object returned from the black box"
#=> TypeError: Object returned from the black box does not respond to method 'each'!
7.aT_equal 8
#=> TypeError: 7:fixnum must be equal to the prescribed value (8:fixnum)!
您可以在YSupport
中自己查找更多这些方法,如果您遗漏了一些内容,欢迎您提供
作为这篇文章的后记脚本,如果您习惯于ActiveSupport
的#present?
方法,那么YSupport
中的运行时断言是:
[].aT_present "supplied array"
#=> TypeError: Supplied array not present!
如果使用ruby 2.0,则可以使用关键字参数:
def foo(x: (fail ArgumentError), y: (fail ArgumentError))
# do stuff with x and y
end
def foo(x:, y:)
# do stuff with x and y
end
在ruby 2.1中,您有适当的必需参数:
def foo(x: (fail ArgumentError), y: (fail ArgumentError))
# do stuff with x and y
end
def foo(x:, y:)
# do stuff with x and y
end
这样,您确实有命名参数(您在问题中称它们为命名参数,但这有点让imho困惑),因此您必须像这样调用方法:
foo(x: 1, y: 2)
如果必须存在
x
和y
,则不要为它们提供默认值。很简单。不幸的是,当前Ruby版本的命名参数需要默认值,这很酷,但我不希望使用monkey patchObject
。不管怎样,谢谢。我在改进之前写的。但是无论如何,在常规编码中,以aE
开头的方法名是非常罕见的,因此它不会对名称空间造成太多的混乱。我确实考虑过这些事情,我认为这是一个可以接受的折衷办法。@synapse:另外,猴子补丁类不限于Object
Array
具有例如强制对象存在的Array#aT#u包括
,强制数组对象唯一性的Array#aT#u uniq
Hash
hasHash#aE\u has
通过ArgumentError
强制所讨论的哈希具有给定的键…+1,我也使用这种技术。不过,有时候,您需要做的不仅仅是fail ArgumentError
。。。