ruby - 在define_method中动态设置参数
问题描述
我有一个类方法::add_method(name, params = {})
,它使用define_method
.
我需要定义方法的参数是关键字参数,具体取决于params
.
class Whatever
def self.add_method(name, params = {})
# do something with params
define_method name do |?|
# some business
end
end
end
目标是当::add_method
调用时:
params = {
foo: { required: false, default: 0 },
bar: { required: true }
}
Whatever.add_method(:hello, params)
然后它创建这个方法:
def hello(foo: 0, bar:)
# some business
end
Nota bene:这不是真正的业务,我已经过度简化了,所以这个问题更容易理解。
解决方案
所以按照建议我去了class_eval
。
class Whatever
class << self
def add_method(name, parameters = {})
class_eval <<-RUBY, __FILE__, __LINE__ + 1
def #{name}(#{method_parameters(parameters)})
#{method_body(parameters)}
end
RUBY
end
# method_parameters({
# foo: { required: false, default: 0 },
# bar: { required: true }
# })
# => "foo: 0, bar:"
def method_parameters(parameters)
parameters.map do |key, options|
value = options[:required] ? '' : " #{options[:default] || 'nil'}"
"#{key}:#{value}"
end.join(', ')
end
# method_parameters({
# foo: { required: false, default: 0 },
# bar: { required: true }
# })
# => "[foo, bar]"
def method_body(parameters)
"[#{parameters.keys.map(&:to_s).join(', ')}]"
end
end
end
params = {
foo: { required: false, default: 0 },
bar: { required: true }
}
Whatever.add_method(:hello, params)
Whatever.new.hello(bar: true) # => [0, true]
Whatever.new.hello(foo: 42, bar: true) # => [42, true]
Whatever.new.hello # missing keyword: bar (ArgumentError)
推荐阅读
- swift - 要设置的字典
- windows - io.Copy 比调用 mv 命令慢很多
- ios - iOS 11 应用提交:“符号文件过多”
- css - 垂直调整窗口大小时,Div 容器消失
- python - 如何替换以 . (时期)?
- python - 从 Pycharm 解析 HDFS 文件
- python - ImportError:无法导入名称 MapTile
- flutter - Flutter 目录不是 GitHub 项目的克隆
- sql-server - TSQL 2012 服务器数据类型错误消息 varchar 转换浮点数(仅 SUM 值)
- mysql - Nginx Puma 和 Rails 5 负载测试失败