Last active
August 29, 2015 14:02
-
-
Save dsalahutdinov/76dc70ec8ef06f51eaa4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Представим, что у нас есть некоторый внешний источник, который возвращает нам данные в виде массива хэшей. | |
# Причём все значения в хэшах передаются как строки. Создайте такой универсальный класс Storage, который позволит | |
# создавать классы преобразователи: | |
require 'time' | |
class Storage | |
def self.attrb(attribute_name, attribute_accessor = nil, &process_proc) | |
raise ArgumentError if attribute_name.nil? | |
unless process_proc.nil? | |
define_method("process_#{attribute_name}") do |value| | |
process_proc.call(value) | |
end | |
return | |
end | |
unless attribute_accessor.nil? | |
define_method("process_#{attribute_name}") do |value| | |
value.send(attribute_accessor) | |
end | |
return | |
end | |
define_method("process_#{attribute_name}") do |value| | |
value | |
end | |
end | |
include Enumerable | |
def each | |
@data.each {|d| yield d } | |
end | |
def initialize(data) | |
@data = data.collect do |data_item| | |
data_item.keys.inject({}) {|hash, key| hash[key] = send("process_#{key}", data_item[key]); hash } | |
end | |
end | |
end | |
class Transactions < Storage | |
attrb :uid # значение будет передаваться как есть | |
attrb :sum, :to_f # для преобразования значения будет вызван его(значения) метод to_f '50.25'.to_f | |
# для преобразования значение будет вызван блок, который принимает исходное значение и возвращает преобразованное | |
attrb :timestamp do |value| | |
Time.parse(value) | |
end | |
def sum | |
@data.collect{|h| h[:sum] }.inject(0) {|s, v| s += v } | |
end | |
end | |
transactions = Transactions.new([ | |
# входной массив хэшей где все значения - строки | |
{:uid => 'HT150', :sum => '50.25', :timestamp => '2014-04-04 05:50'}, | |
{:uid => 'HT151', :sum => '119.63', :timestamp => '2014-04-04 06:18'} | |
]) | |
# а здесь значения преобразованы согласно правилам преобразованиия, описанным в Transactions | |
transactions.to_a | |
# => [{:uid=>"HT150", :sum=>50.25, :timestamp=>2014-04-04 05:50:00 +0600}, {:uid=>"HT151", :sum=>119.63, :timestamp=>2014-04-04 06:18:00 +0600}] | |
transactions.first # => {:uid=>"HT150", :sum=>50.25, :timestamp=>2014-04-04 05:50:00 +0600} | |
transactions.select { |tx| tx[:sum] > 100 } # => [{:uid => 'HT151', :sum => 119.63, :timestamp => 2014-04-04 06:18:00 +0600}] | |
transactions.sum # => 169.88 | |
# для проверки вашего класса Storage я могу создать любой другой класс: | |
class People < Storage | |
attrb :name | |
attrb :height, :to_i | |
attrb :birthday do |value| | |
Date.parse(value) | |
end | |
end | |
ppl = People.new([{:name => 'Vlas', :height => '205', :birthday => '1990-08-08'}]) | |
ppl.first # => {:name => 'Vlas', :height => 205, :birthday => Wed, 08 Aug 1990} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment