我正在尝试使用Ruby在Windows中进行一些脚本化的GUI测试。我正在利用pragprog book的指导,我有点陷入困境。我已经考虑了一些代码来帮助重复映射win32api函数。代码如下:
module WindowsGui
def self.def_api(function, parameters, return_value)
api = Win32API.new 'user32', function, parameters, return_value
define_method(function.snake_case) do |*args|
api.call *args
end
end
end
...所以我可以使用该块以下列方式在模块中定义几个win32API:
def_api 'FindWindow', ['P', 'P'], 'L'
我有一些RSpec测试,以确保它的行为应该如此。
it 'wraps a Windows call with a method' do
find_window(nil, nil).should_not == 0
end
it 'enforces the argument count' do
lambda {find_window}.should raise_error
end
第一次测试时一切正常,第二次导致seg故障。似乎如果我在没有args的情况下调用它,我就无法触摸* args - 但我可以使用args.length来查看它是空的。
为什么会导致seg错误而不是例外?通过类似的东西来解决这个问题是否可以接受。
raise BadArgs if args.length == 0
又一个问题太长了 - 抱歉。
TIA! 鲍勃
答案 0 :(得分:1)
它出现seg错误的可能原因是因为Win32API
下面的某个地方缺少参数正在转换为一个或多个NULL指针解引用。
如果你要创建这样的函数,那么你应该考虑添加一个per-api-call,boolean-returns参数验证块(或lambda)作为def_api
的参数,然后你将调用它作为派生函数的第一部分。像这样:
def self.def_api(function, parameters, return_value, &valid_args?)
api = Win32API.new 'user32', function, parameters, return_value
define_method(function.snake_case) do |*args|
if valid_args? and valid_args?.call(*args)
api.call *args
else
// raise argument error, etc
end
end
end
然后
def_api 'FindWindow', ['P', 'P'], 'L', { |args| return true if // API specific checks succeed }
更新:在提问者的请求中添加更多颜色
&valid_args?
是块参数的名称。 &符号前缀(&)是告诉ruby您传递块的方式。您只能将一个块传递给方法,它必须是参数列表中的最后一个参数。问号后缀(?)只是Ruby编程中用于命名返回布尔值的函数的约定。
如果传递了一个块,则使用&block.call(args)
要使用块参数调用方法,请执行以下操作:
method { |args| // block implementation }
或
method do |args|
// block implementation
end
args
通过call method
传递给该区块。希望这会有所帮助。