Ruby调用带**双splat参数方法报参数数量错误排查
问题诱因
- 核心差异为传入哈希的键类型不一致:测试代码中传入的哈希全部使用符号键,可以被Ruby的
**关键字参数收纳语法正常识别,自动拆分后传入feature方法,因此不会报错。 - 实际运行场景中,
my_helper(:pending)返回的哈希包含字符串键"data-value",和后续合并的符号键:class组成了键类型混合的哈希。在Ruby的参数解析规则下,包含非符号键的哈希不会被自动识别为关键字参数集合,而是会被当作一个完整的普通位置参数传入。 - 此时
feature(label, value, html_options)的调用实际传递了3个位置参数:label为第1个,value为第2个,整个混合键哈希为第3个;但feature方法仅定义了2个位置参数(label、带默认值的style),后续的inverse和html_options都属于关键字参数,不接受额外位置参数,因此抛出参数数量不匹配的错误。 - 旧版调用
<%= create_feature(level, class: 'mr-2') %>能正常运行,是因为传入的哈希全为符号键,会被Ruby自动识别为关键字参数传递,不会被判定为第三个位置参数。
视图层修复方案
仅需要在视图调用时,把传入的哈希全部转为符号键,让Ruby可以正常识别为关键字参数集合即可,修改后的视图代码:
<%= create_feature(level, my_helper(:pending).merge({class: 'mr-2'}).symbolize_keys) %>
如果需要兼容无Rails扩展方法的场景,也可以用Ruby原生方法手动转键类型:
<%= opts = my_helper(:pending).merge({class: 'mr-2'}).transform_keys(&:to_sym) %> <%= create_feature(level, opts) %>
转为纯符号键后,哈希会和测试场景的参数结构一致,被Ruby自动拆分为关键字参数传给feature方法,最终被**html_options正常接收,不会再触发参数数量报错。
内容的提问来源于stack exchange,提问作者Don Giulio
相关产品推荐
相关产品推荐

