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



我有一个这样的标签:

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 ) }

我想提醒的实例变量是基于哈希。

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

我不能使它工作。我尝试了以下操作:

类提醒

attr_accessor: bot_client_id

def initiate(hash)
    # http://stackoverflow.com/questions/1615190/declaring-instance-variables-iterating-over-a-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)

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

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

     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:

Reminder = Struct.new(*reminder_hash.keys.map(&:to_sym))
r = Reminder.new(*reminder_hash.values)
p r.bot_client_id # => "test-client-id"

最新更新