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

时间:2015-10-09 16:19:57

标签: ruby methods hash 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')

我无法让它发挥作用。我尝试了以下方法:

课程提醒

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)

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

2 个答案:

答案 0 :(得分:1)

当然,您可以在初始化方法中执行以下操作:

     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

答案 1 :(得分:0)

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"