开发者

Struct with types and conversion

I am trying to accomplish the following in Ruby:

person_struct = StructWithType.new "Person", 
                                   :name => String, 
                                   :age => Fixnum, 
                                   :money_into_bank_account => Float
开发者_高级运维

And I would like it to accept both:

person_struct.new "Some Name",10,100000.0

and

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

That is, I'd like it to do data conversion stuff automatically.

I know Ruby is dinamically and I should not care about data types but this kind of conversion would be handy.

What I am asking is something similar to ActiveRecord already does: convert String to thedatatype defined in the table column.

After searching into ActiveModel I could not figure out how to to some TableLess that do this conversion.

After all I think my problem may require much less that would be offered by ActiveModel modules.

Of course I could implement a class by myself that presents this conversion feature, but I would rather know this has not yet been done in order to not reinvent the wheel.

Tks in advance.


I think that the implementation inside a class is so easy, and there is no overhead at all, so I don't see the reason to use StructWithType at all. Ruby is not only dynamic, but very efficient in storing its instances. As long as you don't use an attribute, there is none.

The implementation in a class should be:

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

The implementation in StructWithType would then be one layer higher:

  • Implement for each type a converter.
  • Bind an instance of that converter in the class.
  • Use in the new implementation of StructWithType instances (not class) the converters of the class to do the conversion.

A very first sketch of it could go like that:

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

The ideas here are:

  • You have an instance method named create that creates from the factory a new struct instance.
  • The factory iterates through all args (with the index) and searches for each arg the converter to use.
  • It converts the arg with the converter.
  • It stores in the new instance at the argname (method argname[] has to be written) the new value.

So you have to implement the creation of the struct, the lookup for converter, the lookup for the argument name and the setter for the attributes of the new instance. Sorry, no more time today ... I have used create because new has a different meaning in Ruby, I did not want to mess this up.


I have found a project in github that fulfill some of my requirements: ActiveHash. Even though I still have to create a class for each type but the type conversion is free. I am giving it a try.

Usage example:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜