如何在Ruby中定义临时函数?解决测试代码重复与方法泄漏问题
解决方案
1. 使用局部Lambda(最简洁的无泄漏方案)
用局部变量存储Lambda,块结束后变量会被自动回收,不会泄漏到外部作用域。调用时使用.()或[]语法,已经足够简洁:
test 'El.parse_tag' do test_parse_tag = ->(actual, expected) { assert_equal El.parse_tag(actual), expected } test_parse_tag.( 'span', [:span, {}] ) test_parse_tag.( '#id', [:div, { id: 'id' }] ) test_parse_tag.( 'div a=b', [:div, { a: 'b' }] ) end # 外部调用 test_parse_tag 会报错:undefined local variable or method `test_parse_tag'
2. 使用Refinements(Ruby 2.7+)
通过Refinements可以在块内临时给对象添加方法,仅在using生效的范围内可用,外部完全不可见:
test 'El.parse_tag' do refine Object do def test_parse_tag(actual, expected) assert_equal El.parse_tag(actual), expected end end using self test_parse_tag 'span', [:span, {}] test_parse_tag '#id', [:div, { id: 'id' }] test_parse_tag 'div a=b', [:div, { a: 'b' }] end # 外部调用 test_parse_tag 会报错:undefined method `test_parse_tag' for main:Object
3. 临时对象封装
创建临时对象并在其上定义单例方法,仅在对象的instance_eval块内调用,块结束后对象被回收,方法不会泄漏:
test 'El.parse_tag' do helper = Object.new helper.define_singleton_method :test_parse_tag do |actual, expected| assert_equal El.parse_tag(actual), expected end helper.instance_eval do test_parse_tag 'span', [:span, {}] test_parse_tag '#id', [:div, { id: 'id' }] test_parse_tag 'div a=b', [:div, { a: 'b' }] end end # 外部无法调用 test_parse_tag
内容的提问来源于stack exchange,提问作者Alex Craft
相关产品推荐
相关产品推荐

