如何使用Ruby Metapraogramming对嵌套哈希键使用链点表示法

问题描述 投票:0回答:1

我正在编写一个函数from scratch,该函数在构造函数中使用哈希。请注意,在Ruby中,构造函数是该类的一种特殊方法,每当创建该类的实例时,该方法便会自动被调用。但是,我的某些RSpec测试未通过或无法运行because I couldn't implement it in the code

code

class Config
  attr_accessor :a1, :a2, :a3, :a4

  def initialize(args)
    if args.is_a? Hash
      args.each do |k, v|
        instance_variable_set("@#{k}", v) unless v.nil?
      end
    else
      raise ArgumentError, "Invalid argument. Supply a Hash instead of #{args.class}"
    end
  end

  def method_missing(method_name, *args, &block)
    return nil if method_name.empty?

    if args.include?(method_name.to_sym)
      send(args[method_name.to_sym], *args, &block)
    else
      raise ArgumentError, "Method `#{method_name}` doesn't exist."
    end

    super
  end

  def respond_to_missing?(method, include_private = false)
    args.respond_to?("get_#{method}_info") || super
  end
end

rspec

describe Config do
  conf = Config.new({a1: 'test', 'a2' => {'a3' => [20, 21]}, a4: {}})

  it 'should' do
    expect(conf.a2.a3).to eq([20, 21])
  end
end

我试图检查我的代码并运行puts conf.a2.a3,我得到:

未捕获的异常:{“ a3” => [20,21]}的未定义方法'a3':哈希]]

[如果有人可以提供帮助,我会感到很高兴。它适用于conf.a1conf.a4,但我当然不知道如何使它响应点标记(例如conf.a2.a3)的链接并适当地返回值。如果您有其他解决方法,请给我指路。

谢谢

我正在从头开始编写一个函数,该函数在构造函数中使用哈希。请注意,在Ruby中,构造函数是该类的特殊方法,只要...

ruby rubygems metaprogramming
1个回答
1
投票

您的测试不起作用,因为conf.a2返回一个Hash(它不响应消息a3)。我无法确切地说出您要完成的工作,但是看起来您可以通过确保每当您返回一个原本为Hash的值时,该值便成为Config类的实例,从而使测试通过。 >

奇怪的是,您已经为平面名称列表定义了attr_accessors,但是您是以结构化的方式访问名称的,而不是您所定义的平面列表。

© www.soinside.com 2019 - 2024. All rights reserved.