Ruby中如何在哈希中存储Net::HTTP请求类并正确调用?
直接存储类引用即可实现需求
完全不需要提前实例化请求类,也不需要绕方法符号的调用链路,直接把类本身存在哈希里就能实现等价逻辑。
两个报错的触发原因
- 提前实例化写法的报错:
Net::HTTP::Get、Net::HTTP::Post这类类的初始化方法必须传入uri参数才能完成实例化,你在定义常量时直接调用.new却不传任何参数,自然会抛出参数数量不匹配的ArgumentError。 - 直接存类写法的报错:你当时是把类对象传给了
public_send当第一个参数用,但public_send的第一个入参必须是当前作用域下可调用的方法名(符号或字符串),传类对象根本不符合方法查找的要求,自然会抛出类型不匹配的TypeError。这个是调用方式和存的内容类型不匹配,不是类不能存的问题。
可直接运行的正确实现
哈希只存类的引用,在实际发起请求时再传入uri参数完成实例化即可,和你想要的“按key匹配请求类型、生成对应uri的请求对象”的逻辑完全对齐:
# 仅存储类本身的引用,不做提前实例化 REQUESTS = { get: Net::HTTP::Get, post: Net::HTTP::Post, patch: Net::HTTP::Patch } def request(req, uri) request_klass = REQUESTS[req.to_sym] # 可选兜底:对不支持的请求类型抛出明确异常 raise ArgumentError, "不支持的请求方法: #{req}" unless request_klass # 直接传入uri参数实例化对应类 request_klass.new(uri) end # 调用方式和你之前设计的完全一致 request("get", "https://api.randomsite.com")
和你存方法符号的示例的逻辑差异
你写的TEST哈希示例,存的是当前对象的实例方法对应的符号,所以必须靠public_send做方法查找、触发调用;而Net::HTTP::Get这类类是Ruby中的一等对象,根本不需要走当前对象的方法查找流程,直接持有类引用、调用实例化方法即可,还能省去符号解析、方法查找的冗余开销。
内容的提问来源于stack exchange,提问作者Sanico
相关产品推荐
相关产品推荐

