gpt4 book ai didi

ruby - 在 Ruby 中装饰一个方法

转载 作者:数据小太阳 更新时间:2023-10-29 08:19:44 25 4
gpt4 key购买 nike

我有一个方法将整数数组作为参数,我想使用装饰器模式首先验证数组中的每个数字是否在指定范围内。

我在 ruby​​ 中看到过扩展类或包含模块的装饰器,但这对我来说似乎有点过分,有没有办法只装饰一个方法而不依赖于类或模块?

编辑我有几种方法将数组作为参数,并且需要验证项目的范围。我不想在每个方法中对验证进行内联编码,而是希望所有这些方法都有一个装饰器,但我想知道装饰器类/模块是否是 Ruby 中唯一存在的类/模块?

class MyClass
..some code here ...
def method(array)
..some code here...
end
end

最佳答案

这是一个如何使用验证器包装方法的简单示例:

class Foo
def foo(a, b, c)
p a, b, c
end

def bar(a, b)
p a, b
end

validate(:foo, :bar) {|*args, &blk| args.reduce(:+) == 6 }
end

Module#validate 方法接受一个方法名称列表,以及一个包含这些方法验证逻辑的 block 。

foo = Foo.new

foo.foo(1, 2, 3)
# 1
# 2
# 3

foo.bar(2, 4)
# 2
# 4

foo.foo(2, 3, 4)
# [2, 3, 4] (Validator::ValidationError)

foo.bar(2, 3)
# [2, 3] (Validator::ValidationError)

如您所见,验证器在最后两次调用中拒绝了参数列表,因为它们没有通过 block 中的条件。

这就是让这一切发生的“魔力”,但实际上并不是那么魔力。我们生成一个模块,它覆盖了我们想要验证的方法,如果验证失败,则引发异常,然后简单地调用super .然后我们将该模块添加到我们当前所在的类/模块,即调用validate 方法所在的类/模块。基本上就是这样。

我选择也成为一名优秀的 Ruby 公民,并将整个事情包装在一个 Refinement 中,所以你需要说

using Validator

实际激活它。

module Validator
class ValidationError < ArgumentError; end

refine Module do
def validate(*methods, &validator)
prepend(Module.new do
methods.each do |method|
define_method(method) do |*args, &blk|
raise ValidationError, args.inspect unless yield *args
super(*args, &blk)
end
end
end)
end
end
end

关于ruby - 在 Ruby 中装饰一个方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37559248/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com