我有一个这样的标签:
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"