我可以将散列传递给实例方法来创建实例变量吗?

can I pass a hash to an instance method to create instance variables?

我有一个这样的:

reminder_hash = {"bot_client_id"=>"test-client-id", "recurring"=>true, "recurring_natural_language"=>"everyday", "time_string"=>"10AM", "time_zone"=>"America/Los_Angeles", "via"=>"slack", "keyword"=>"test-keyword", "status"=>"active", "created_time"=>1444366166000}

我想传递给这样的方法(来自 Rspec):

let(:reminder) { Reminder.new( reminder_hash ) }

我希望 Reminder 的实例变量基于散列。

expect(reminder.bot_client_id).to eq('test-client-id')

我无法让它工作。我尝试了以下方法:

class 提醒

attr_accessor :bot_client_id

def initiate(hash)
    # 

    hash.each do |k,v|

      instance_variable_set("@#{k}",v)
      # if you want accessors:

      eigenclass = class<<self; self; end

      eigenclass.class_eval do

        attr_accessor k
      end

    end

  end

Rspec 给出以下错误:

Failure/Error: let(:reminder) { Reminder.new( reminder_hash ) }
 ArgumentError:
   wrong number of arguments (1 for 0)

问题:如何将散列传递给对象的实例方法,使散列值成为新创建对象的实例变量?

当然你可以在你的初始化方法中做这样的事情:

     hash.each do |k, v|
        instance_variable_set("@#{k}", v)
        self.class.send(:attr_reader, k)
      end

这是一个使用您的输入哈希的示例:

class Reminder
  def initialize(hash)
    hash.each do |k, v|
      instance_variable_set("@#{k}", v)
      self.class.send(:attr_reader, k)
    end
  end
end


reminder_hash = {"bot_client_id"=>"test-client-id", "recurring"=>true, "recurring_natural_language"=>"everyday", "time_string"=>"10AM", "time_zone"=>"America/Los_Angeles", "via"=>"slack", "keyword"=>"test-keyword", "status"=>"active", "created_time"=>1444366166000}

reminder = Reminder.new(reminder_hash)
puts reminder

puts reminder.bot_client_id

输出:

#<Reminder:0x007f8a48831498>
test-client-id

Ruby OpenStruct 可以做到这一点。

require 'ostruct'

reminder_hash = {"bot_client_id"=>"test-client-id", "recurring"=>true, "recurring_natural_language"=>"everyday", "time_string"=>"10AM", "time_zone"=>"America/Los_Angeles", "via"=>"slack", "keyword"=>"test-keyword", "status"=>"active", "created_time"=>1444366166000}
reminder = OpenStruct.new(reminder_hash)

p reminder.bot_client_id # => "test-client-id"

使用 Struct 实现完整 Class:

Reminder = Struct.new(*reminder_hash.keys.map(&:to_sym))
r = Reminder.new(*reminder_hash.values)

p r.bot_client_id # => "test-client-id"