Структура с типами и преобразованием - PullRequest
0 голосов
/ 20 сентября 2011

Я пытаюсь выполнить следующие действия в Ruby:

person_struct = StructWithType.new "Person", 
                                   :name => String, 
                                   :age => Fixnum, 
                                   :money_into_bank_account => Float

И я хотел бы принять оба:

person_struct.new "Some Name",10,100000.0

и

person_struct.new "Some Name","10","100000.0"

То есть мне бы хотелось, чтобы он автоматически выполнял преобразование данных.

Я знаю, что Ruby динамически, и мне не нужно заботиться о типах данных, но такой тип преобразования будет полезен.

ЧтоЯ спрашиваю, что-то похожее на ActiveRecord уже делает: преобразовать String в тип данных, определенный в столбце таблицы.

После поиска в ActiveModel я не мог понять, как некоторые TableLess, которые делают это преобразование.

В конце концов, я думаю, что моей проблеме может потребоваться гораздо меньше, чем было бы предложено модулями ActiveModel.

Конечно, я мог бы сам реализовать класс, который представляет эту функцию преобразования, но я бы предпочел, чтобы этого еще не было.было сделано для того, чтобы не изобретать велосипед.

ТКС заранее.

Ответы [ 2 ]

0 голосов
/ 13 октября 2011

Я нашел проект в github, который удовлетворяет некоторым моим требованиям: ActiveHash .Хотя мне все еще нужно создать класс для каждого типа, но преобразование типов бесплатное.Я даю ему попытку.

Пример использования:

class Country < ActiveHash::Base
  self.data = [
                {:id => 1, :name => "US"},
                {:id => 2, :name => "Canada"}
              ]
end

country = Country.new(:name => "Mexico")
country.name  # => "Mexico"
country.name? # => true
0 голосов
/ 20 сентября 2011

Я думаю, что реализация внутри класса очень проста, и никаких накладных расходов вообще нет, поэтому я не вижу смысла использовать StructWithType вообще. Ruby не только динамичен, но и очень эффективен для хранения своих экземпляров. Пока вы не используете атрибут, его нет.

Реализация в классе должна быть:

def initialize(name, age, money_into_bank_account)
  self.name = name
  self.age = age.to_i
  self.money_into_bank_account = money_into_bank_account.to_f
end

Реализация в StructWithType будет тогда на один уровень выше:

  • Реализуйте для каждого типа конвертер.
  • Свяжите экземпляр этого конвертера в классе.
  • Используйте в реализации new экземпляров StructWithType (не классов) преобразователи класса для выполнения преобразования.

Самый первый набросок этого может выглядеть так:

class StructWithType
  def create(args*)
    <Some code to create new_inst>
    args.each_with_index do |arg,index|
      new_value = self.converter[index].convert(arg)
      new_inst[argname[index]]= new_value
    end
  end
end

Идеи здесь:

  • У вас есть метод экземпляра с именем create, который создает из фабрики новый экземпляр структуры.
  • Фабрика перебирает все аргументы (с индексом) и ищет каждый аргумент, который будет использовать конвертер.
  • Конвертирует arg с конвертером.
  • Он сохраняет в новом экземпляре в argname (метод argname[] должен быть записан) новое значение.

Таким образом, вы должны реализовать создание структуры, поиск преобразователя, поиск имени аргумента и установщик атрибутов нового экземпляра. Извините, больше нет времени сегодня ... Я использовал create, потому что new имеет другое значение в Ruby, я не хотел это испортить.

...