Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 干涸的论证检验_Ruby - Fatal编程技术网

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 patch
Object
。不管怎样,谢谢。我在改进之前写的。但是无论如何,在常规编码中,以
aE
开头的方法名是非常罕见的,因此它不会对名称空间造成太多的混乱。我确实考虑过这些事情,我认为这是一个可以接受的折衷办法。@synapse:另外,猴子补丁类不限于
Object
Array
具有例如强制对象存在的
Array#aT#u包括
,强制数组对象唯一性的
Array#aT#u uniq
Hash
has
Hash#aE\u has
通过
ArgumentError
强制所讨论的哈希具有给定的键…+1,我也使用这种技术。不过,有时候,您需要做的不仅仅是
fail ArgumentError
。。。