2015-10-09 2 views
1

У меня есть еще так:Могу ли я передать хэш методу экземпляра для создания переменных экземпляра?

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) 

Вопрос: Как передать хэш Ань метод экземпляра для объекта, так что значения хэша являются переменными экземпляра для этого вновь созданного объекта?

ответ

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 
+0

я вижу. Почему в моей версии произошла ошибка неправильных аргументов! – Angela

+0

Это выглядит великолепно. Попробуй сейчас. – Angela

+0

приятно работает @ Энтони! – Angela

0

Рубин 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" 
+0

Как создать класс напоминания с помощью openstrict? – Angela

+0

@Angela не с Openstruct, а с помощью Struct - см. Отредактированный ответ. – steenslag

+0

Я вижу, это выглядит интересно ..... – Angela