2011-09-20 80 views
0

我试图做到在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是dinamically,我不应该关心数据类型,但这种转换将是方便的。

我在问的是类似于ActiveRecord的东西:将String转换为表列中定义的数据类型。

在搜索到ActiveModel后,我无法弄清楚如何执行此转换的一些TableLess。

毕竟我认为我的问题可能需要少得多的ActiveModel模块提供。

当然,我可以自己实现一个类,提供这种转换功能,但我宁愿知道,为了不重新发明轮子,还没有完成这项工作。

TKS提前。

+0

[宝石了Virtus(https://github.com/solnic/virtus)完成正是我一直在找。 – pisaruk

回答

0

我认为类内的实现非常简单,没有任何开销,所以我根本没有看到使用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 

在这里的想法是:

  • 您有一个名为创建从工厂一个新的结构创建一个实例方法实例。
  • 工厂遍历所有参数(使用索引)并搜索转换器使用的每个arg。
  • 它用转换器转换arg。
  • 它存储在新实例中的argname(必须写入方法argname[])新值。

所以你必须实现struct的创建,转换器的查找,参数名称的查找以及新实例属性的setter。对不起,今天没有更多的时间... 我已经使用create,因为new在Ruby中有不同的含义,我不想搞砸了。

+0

Tks为您的答案。我试图避免创建类,因为一个类需要一个名称,而我只捆绑了很多属性,我不想在某些特定的想法下进行分组。假设我有属性:姓名,性别和年龄。我应该创建另一个类:Person2?当然,我可以通过创建很多os类来重构整个系统,但我不认为这是值得的。 – pisaruk

0

我在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