有一种方法通常使用命名参数调用,它看起来像这样
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
或
class Foo
required_arguments :bar, :x, :y
def bar(x = nil, y = nil)
end
end
我尝试用alias_method_chain
实现第二种方法,但问题是在我的实用程序模块的上下文中评估了__method__
,所以我无法访问我需要的方法的参数校验。有什么想法吗?
答案 0 :(得分:3)
如果您使用ruby 2.0,则可以使用关键字参数:
def foo(x: (fail ArgumentError), y: (fail ArgumentError))
# do stuff with x and y
end
在ruby 2.1中你有适当的必要参数:
def foo(x:, y:)
# do stuff with x and y
end
这样你实际上有了命名参数(你在问题中称它们为命名参数,但这有点令人困惑),所以你必须调用这样的方法:
foo(x: 1, y: 2)
答案 1 :(得分:0)
value of such run-time assertions is limited,但它们确实有用。我已将它们纳入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
的{{1}}方法,#present?
中的运行时断言是:
YSupport